所有实体类都会有一些公共属性,可以把这些属性定义到一个父类中。比如:抽象类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>()等效