【手擼一個ORM】使用說明
阿新 • • 發佈:2019-04-07
ttr 內容 reat lse 列名 def each test eat
傳送門
- 【手擼一個ORM】第一步、約定和實體描述
- 【手擼一個ORM】第二步、封裝實體描述和實體屬性描述
- 【手擼一個ORM】第三步、SQL語句構造器和SqlParameter封裝
- 【手擼一個ORM】第四步、Expression(表達式目錄樹)擴展
- 【手擼一個ORM】第五步、查詢條件表達式目錄樹解析和插入、更新查詢目錄樹解析
- 【手擼一個ORM】第六步、對象表達式解析和Select表達式解析
- 【手擼一個ORM】第七步、SqlDataReader轉實體
- 【手擼一個ORM】第八步、實體查詢和按需查詢
- 【手擼一個ORM】第九步、orm默認配置類
- 【手擼一個ORM】第十步、數據庫查詢工具類 MyDb
約定
數據實體對象繼承自 IEntity 接口,該接口定義了一個 int 類型的Id屬性。
public interface IEntity { int Id { get; set; } } // 數據實體類 public class Student : IEntity { public int Id { get; set; } public string Name { get; set; } public int ClazzId { get; set; } public Clazz Clazz { get; set; } // 更新時忽略該屬性 [MyColumn(UpdateIgnore = true)] public DateTime CreateAt { get; set; } } public class Clazz : IEntity { public int Id { get; set; } public string Name { get; set; } }
導航屬性
如上面定義的Student類,導航屬性Clazz默認外鍵為ClazzId,如需顯式指定外鍵,可使用[MyForeignKey("FKClazzId")]修飾Clazz屬性,這樣查詢時就可以通過Include(s => s.Clazz)查找到相關的Clazz信息,默認僅支持Left Join。
實體描述
MyTableAttribute(string tableName)
用於描述實體類,若實體名稱與表名不同,需要使用此描述指定表名
MyKeyAttribute(string keyName)
用於描述實體的主鍵,若主鍵列不為Id,需使用詞描述指定主鍵對應的列名
MyColumnAttribute(string ColumnName,bool Ignore,bool InsertIgnore, bool UpdateIgnore)
列描述,可指定對應的列名,Ignore=true 插入和修改時都忽略此字段,InsertIgnore=true 插入時忽略, UpdateIgnore=true 修改時忽略
MyForeignKeyAttribute(string ForeignKey, string MasterKey)
若外鍵名非 導航屬性名+"Id",則需通過ForeignKey指定,MasterKey默認為Id,若不是通過Id進行關聯或關聯表的主鍵名不是Id,則需要通過此MasterKey指定
用法
實例化對象:
var db = new MyDb("DataSource=.;Database=Test;USER ID=sa;Password=1234"); // 或者在global中定義默認配置,使用時只要 var db = MyDb.New(); 即可。 // MyDb.New()等同於 new MyDb(); MyMiniOrmConfiguration.Init(ConfigurationManager.AppSettings["DefaultConnectionString"]);
查詢單個實體:
var student = db.Load<Student>(1); var student = db.Load<Student>(s => s.Name == "張三");
查詢多個實體:
var student = db.Fetch<Student>(); var student = db.PageList<T>(2, 10, out var recordCount, s => s.Name.Contains("張三"), s=>s.Name);
Fluent 查詢
var query = db.Query<Student>() .Include(s => s.Clazz) .Where(s => s.CreateAt > DateTime.Today.AddDays(-1)) .OrderBy(s => s.Clazz.Id) .ThenOrderByDesc(s => s.Name); var student = query.FirstOrDefault(); var students = query.ToList(); var students2 = query.ToPageList(2, 2, out var recordCount);
Select 查詢
var query = db.Query<Student>() .Include(s => s.Clazz) .Where(s => s.CreateAt > DateTime.Today.AddDays(-1)) .OrderBy(s => s.Clazz.Id) .ThenOrderByDesc(s => s.Name); var student = query.Select<StudentDto>(s => new StudentDto { s.Id, s.StudentName, SchoolName = s.School.Name }).ToList(); var student = query.Select<StudentDto>(s => new StudentDto { s.Id, s.StudentName, SchoolName = s.School.Name }).ToPageList(2, 2, out var recordCount);
插入
var student = new Student { Name = "張三", ClazzId = 1, CreateAt = DateTime.Now }; db.Insert(student); // 會將新產生的Id賦值到student.Id屬性 Console.WriteLine($"{student.Id}"); // 批量插入 var students = new List<Student> { new Student {Name = "張三", ClazzId = 1, CreateAt = DateTime.Now}, new Student {Name = "李四", ClazzId = 1, CreateAt = DateTime.Now}, new Student {Name = "王五", ClazzId = 1, CreateAt = DateTime.Now}, new Student {Name = "趙六", ClazzId = 1, CreateAt = DateTime.Now} }; db.Insert(students); foreach (var stu in students) { Console.WriteLine($"{stu.Id}-{stu.Name}"); } // 如果不存在,則插入 // 如限制用戶名不能重復 InsertIfNotExist(user, u => u.Name == user.Name) int InsertIfNotExists<T>(T entity, Expression<Func<T, bool>> where) where T : class, IEntity, new()
更新
var student = db.Load<Student>(1); student.Name = student.Name + "修改過"; var result = db.Update(student); // 批量更新 var students = db.Fetch<Student>(s => s.Id > 1); foreach (var student in students) { student.Name += student.Name + "批量修改過"; } var count = db.Update(students); Console.WriteLine($"修改了 {count} 行"); // 如果不存在則更新 // UpdateIfNotExists(user, u=>u.Name == user.Name && u.Id != user.Id) int UpdateIfNotExits<T>(T entity, Expression<Func<T, bool>> where)
更新-註意,以下內容未經過測試
// 通過Id修改指定列 db.Update<Student>(1, DbKvs.New().Add("Name", "張三")); var student = db.Load<Student>(1); student.Name = student.Name + "測試修改"; student.ClazzId = 2; // 更新指定對象的指定屬性(指定忽略屬性) // 註意,下面方法傳入的是屬性名而不是列名 var count = db.UpdateInclude<Student>(student, new[] {"Name", "ClazzId"}); var count2 = db.UpdateInclude<Student>(student, s => new { s.Name, s.ClazzId }; var count3 = db.UpdateIgnore<Student>(student, new[] {"CreateAt"}); var count4 = db.UpdateInclude<Student>(student, s => new { s.CreateAt, s.Creator, s.IsDel }; // 通過指定條件修改指定列,註意第一個參數傳入的是屬性名而不是列名 db.Update<Student>(DbKvs.New().Add("ClazzId", 2), s => s.ClazzId == 1);
刪除
// 如果實體繼承ISoftDelete,此方法將IsDel列賦值為0,可通過傳入 isForce=true,強制delete // int Delete<T>(int id, bool isForce = false) where T : class, IEntity, new() db.Delete<Student>(1, true); // int Delete<T>(IEnumerable<int> idList, bool isForce = false) where T : class, IEntity, new() db.Delete<Student>(new[] {1,2,3}, true);
【手擼一個ORM】使用說明