所有實體類都會有一些公共屬性,可以把這些屬性定義到一個父類中。比如:抽象類BaseEntity
public abstract class BaseEntity { public long Id { get; set; } public bool Isdelete { get; set; }=false public DateTime CreateTime { get; set; }=DateTime.Now public DateTime DeleteTime { get; set; } public abstract void Do(); }
public class Person:BaseEntity { public string Name { get; set; } public override void Do() { Console.WriteLine("eat"); } }
public class Student:Person { public string StuNo { get; set; }
public virtual Class Class { get; set; } }
public class Teacher:Person { public int Salary { get; set; } }
public class MyContext:DbContext { public MyContext():base("conn") { Database.SetInitializer<MyContext>(null); } public DbSet<Student> Students { get; set; } public DbSet<Teacher> Teachers { get; set; }
public DbSet<Class> Classes { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly()); } }
使用公共父類的好處不僅是寫實體類簡單了,而且可以提供一個公共的實體操作類;
public class CommonCRUD<T> where T:BaseEntity //T是泛型,T必須是繼承BaseEntity的類,泛型約束 { private MyContext ctx; public CommonCRUD(MyContext ctxs) { this.ctx = ctxs; } public void MarkDeleted(long id) { T item= ctx.Set<T>().Where(e => e.Id == id).SingleOrDefault();//因為約束了類需要繼承BaseEntity,所以可以點出Id if(item== null) { throw new ArgumentException("找不到id=" + id + "數據"); } else { item.Isdelete = true; item.DeleteTime = DateTime.Now; ctx.SaveChanges(); } } public T GetById(long id) { T item = ctx.Set<T>().Where(e => e.Id == id && e.Isdelete == false).SingleOrDefault(); return item; } public IQueryable<T> GetAll(int start,int Count) { return ctx.Set<T>().OrderBy(e => e.CreateTime).Skip(start).Take(Count).Where(e => e.Isdelete == false); } public long GetTotalCount() { return ctx.Set<T>().Where(e => e.Isdelete == false).LongCount(); } }
測試:
static void Main(string[] args) { using (MyContext ctx = new MyContext()) { Teacher t1 = new Teacher() { Name = "語文老師", Salary = 1200 }; Teacher t2 = new Teacher() { Name = "數學老師", Salary = 2400 }; Teacher t3 = new Teacher() { Name = "英語老師", Salary = 800 }; //增加 /* ctx.Set<Teacher>().Add(t1); ctx.Set<Teacher>().Add(t2); ctx.Set<Teacher>().Add(t3); ctx.SaveChanges(); */ CommonCRUD<Teacher> crud = new CommonCRUD<Teacher>(ctx); //刪除 //crud.MarkDeleted(1); //查詢 var Ts= crud.GetAll(0, 10); foreach (var item in Ts) { Console.WriteLine(item.Name); } } Console.WriteLine("ok"); Console.ReadKey(); }
為什么用IQueryable,因為性能比IEnumerable高,用IEnumerable后續是在內存中操作的;
public class Class:BaseEntity { public override void Do() { } public string Name { get; set; } }
測試:
static void Main(string[] args) { using (MyContext ctx = new MyContext()) { Class c1 = new Class { Name = "三年二班" }; Student s1 = new Student(){ Name = "chen", StuNo = "10002", Class = c1 }; Student s2 = new Student(){ Name = "wang", StuNo = "10003", Class = c1 }; ctx.Students.Add(s1); ctx.Students.Add(s2); ctx.SaveChanges(); CommonCRUD<Student> crud = new CommonCRUD<Student>(ctx); //對於IQueryable也可以調用Include,需要using System.Data.Entity; var Ts = crud.GetAll(0, 10).Include(e =>e.Class); foreach (var item in Ts) { Console.WriteLine(item.Name); Console.WriteLine(item.Class.Name); } } Console.WriteLine("ok"); Console.ReadKey(); }
為什么BaseEntity是抽象類
設為抽象類是避免被實例化,讓這個類只能作為基類參與繼承,不能讓他new出來
Set<T>()是 DBSet<T>的一個屬性嗎?
db.Teachers的本質就是db.Set<Teachers>()吧?
Set<T>就是上下文類中的一個方法,可以操作指定實體類來改變數據庫。
db.Teachers和db.Set<Teachers>()等效
