EF(EntityFrameWork) ORM(对象关系映射框架/数据持久化框架),根据实体对象操作数据表中数据的一种面向对象的操作框架,底层也是调用ADO.NET
ASP.NET MVC 项目会自动导入MVC程序集,因为默认.NET环境(GAC)中没有这个程序集
1: EF数据上下文 继承于 DbContext ; DBQuery<T> ,支持延迟加载:只有当使用到数据的时候,才去查询数据库; 主要成员:表映射的实体集合 Set<T>,Entry<T>()
context.Model -->Dbset<Model>
context.set<Model>() -->Dbset<Model>
//使用状态版的时候,执行修改/删除的时候必须指定主键。
2: EF中会为每个 管理的 实体对象 创建一个代理包装类对象,其中会跟踪 实体对象 的状态和每个属性的状态;
3: [EF对象管理容器]: 每个通过EF数据上下文操作的实体对象,都需要存在上下文的容器中,一旦通过上下文的某个方法操作了实体对象后,那么上下文就会给它加一个状态标识。
但调用上下文的SaveChanges方法的时候,上下文就会遍历容器中的所有对象,并检查他们的状态标识,并依照标识的值进行相应的增删改查sql操作
一、通常使用EF更新的方式,先查询出要修改的数据,然后再修改新的值;
实体对象被修改的属性 在 代理包装类对象里 的对应属性状态会被修改记录下修改状态,等到调用SaveChanges时,EF会遍历其管理的每个实体对象,并根据其 包装类对象 的状态,生成增删改查sql语句并执行;
此例中修改操作,会生成 修改的sql语句(注意:此处只为修改过的属性生成sql语句),最后执行。
1 2 3 4 5 6 7 8 9 10 |
//EF context 对象 MyFirstEFEntities context = new MyFirstEFEntities(); //update //1:先查询要修改的原数据 CustomerInfo customer = context.CustomerInfoes.Find(1); //2:设置修改后的值 customer.customerDate = DateTime.Now; //3:更新到数据库 context.SaveChanges(); |
二、为避免先查询数据库,可以直接将 被修改的实体对象 添加到 EF中管理(此时为附加状态Attached),并手动设置其为未修改状态(Unchanged),同时设置被修改的实体对象的包装类对象 对应属性为修改状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//EF context 对象 DbContext contextState = new MyFirstEFEntities(); //update CustomerInfo customerState = new CustomerInfo(); customerState.id = 1; customerState.customerDate = DateTime.Now; customerState.customerName = "bbb"; //1: 标记当前对象,必须把必填字段都填写,否则会报错:System.Data.Entity.Validation.DbEntityValidationException //1: 若此时未更新 非必填字段,则数据库会把非必填字段更新为null contextState.Entry<CustomerInfo>(customerState).State = System.Data.EntityState.Modified;//设置字段状态为全部更新,适合更新字段多,不更新字段少的情况 entry.Property("customerName").IsModified = false;//字段不更新,此字段更新不会保存到数据库 contextState.SaveChanges(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//EF context 对象 DbContext contextState = new MyFirstEFEntities(); //update 2 CustomerInfo customerState = new CustomerInfo(); customerState.id = 1; customerState.customerName = "dfdfdfdf"; //2: 针对某个属性,进行状态跟踪设置 //** 2.1: 如果使用 Entry 附加 实体对象到数据容器中,则需要手动 设置 实体包装类的对象 的 状态为 Unchanged** //** 2.1: entry.State = System.Data.EntityState.Unchanged; DbEntityEntry<CustomerInfo> entry = contextState.Entry<CustomerInfo>(customerState); entry.State = System.Data.EntityState.Unchanged;//设置全字段不更新,适合更新部分字段少,不更新字段多的情况 entry.Property("customerName").IsModified = true;//字段更新 contextState.SaveChanges(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//EF context 对象 DbContext contextState = new MyFirstEFEntities(); //update 3 CustomerInfo customerState = new CustomerInfo(); customerState.id = 1; customerState.customerName = "aaaaa"; //** 2.2: 如果使用 Attach 就不需要这句 //** 2.2: entry.State = System.Data.EntityState.Unchanged; contextState.Set<CustomerInfo>().Attach(customerState);//设置全字段未更新,适合需要更新字段少的情况,/直接针对属性进行状态设置,但是当前对象并没有被上下文跟踪 contextState.Entry<CustomerInfo>(customerState).Property("customerName").IsModified = true;//设置为字段已更新,其它的不更新到库中 contextState.SaveChanges(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#region 多表增加操作 DbContext dbContext = new MyFirstEFEntities(); CustomerInfo customerInfo = new CustomerInfo() { customerName = "duobiaocaozuo", customerDate = DateTime.Now }; dbContext.Set<CustomerInfo>().Add(customerInfo); OrderInfo orderInfo1 = new OrderInfo() { orderName = "bike1", customerId = customerInfo.id }; dbContext.Set<OrderInfo>().Add(orderInfo1); OrderInfo orderInfo2 = new OrderInfo() { orderName = "bike2", customerId = customerInfo.id }; dbContext.Set<OrderInfo>().Add(orderInfo2); dbContext.SaveChanges(); #endregion |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#region 导航属性 DbContext dbContext = new MyFirstEFEntities(); CustomerInfo customerInfo = new CustomerInfo() { customerName = "daohangshuxing", customerDate = DateTime.Now }; customerInfo.OrderInfoes.Add(new OrderInfo() { orderName = "car1", }); customerInfo.OrderInfoes.Add(new OrderInfo() { orderName = "car2" }); dbContext.Set<CustomerInfo>().Add(customerInfo); dbContext.SaveChanges(); #endregion |
参考文章:
ASP.NET EF(LINQ/Lambda查询):http://www.cnblogs.com/Dr-Hao/p/5356928.html
ASP.NET EF 使用LinqPad 快速学习Linq:http://www.cnblogs.com/Dr-Hao/p/5357112.html
Ps:ViewBag,ViewData,TempData区别?
ViewBag 和 ViewData 数据"共享",作用域为 当前 Action。
TempData 作用域跨 Action。