EntityFramework是一个很不错的ORM框架,一直都在使用。今天想跟你们分享如下EntityFramework数据更新方面的几个技巧:
1:如何new一个新实体去更新记录,而不是从数据库中查询一条记录来更新。
2:如何在更新实体的同时,对导航属性的实体进行一系列的操做。
3:如何用最简单的代码实现实体的部分更新。数据库
1 new一个新实体去更新记录框架
EntityFramework有一个特色,你无须查询出一个记录,而是new一个新实体,而后对其进行删除或更新操做,只须提供实体的ID便可,若是ID不存在将会抛出异常。这样有助于提升性能,毕竟减小了一次数据库访问。要实现用一个新实体去更新记录,你得让EF的Change Tracker跟踪该实体,让它认为该实体就是从数据库中取出来的,只要让改该实体处于修改状态就好了,代码以下:ide
1 context.Entry<TEntity>(entity).State = EntityState.Modified; 2 context.SaveChanges();
2 更新实体时操做导航属性
用一个例子来讲明在更新实体同时如何对导航属性进行操做吧。假设有两个类型
public class Customer
{
public string ID { get; set; }
public string Name { get; set; }
public IList<CustomerAddress> CustomerAddresses { get; set; }
}性能
public class CustomerAddress
{
public string City { get; set; }
public string ZipCode { get; set; }
public string CustomerId { get; set; }
public Customer Customer { get; set; }
}
那如何在更新Customer的同时Add一个CustomerAddress而且Delete一个CustomerAddress呢?关键一点就是要让EntityFramework的Change Tracker知道有CustomerAddress的存在,只需对Customer增长一个Add操做就好了,代码以下:spa
1 public void Modify(Customer entity,CustomerAddress address) 2 { 3 context.Customer.Add(entity); 4 5 //修改Customer 6 context.Entry(entity).State = EntityState.Modified; 7 8 //新增CustomerAddress 9 if (......) 10 { 11 entity.CustomerAdresses.Add(address); 12 } 13 14 //删除CustomerAddress 15 if (.......) 16 { 17 context.Entry(address).State = EntityState.Deleted; 18 } 19 context.SaveChanges(); 20 }
若是注释掉context.Customer.Add(entity)这行代码,将会抛出异常,这个是值得注意的地方。code
3 实现实体的部分更新
之前好像在园子里有朋友讲过Entityframework实体部分更新的问题,就是用反射去遍历实体的属性,把须要修改的实体属性状态设置为Modified,这样也能够达到目的,可是这样写的代码有点多,并且对Entityframework的特性没有充分的利用,其实很简单两行代码就搞定:blog
1 /// <summary> 2 /// 实体部分更新 3 /// </summary> 4 /// <param name="originalEmployee">需修改的实体</param> 5 /// <param name="newEmployee">新的实体</param> 6 public void Modify(Employee originalEmployee, Employee newEmployee) 7 { 8 context.Entry(originalEmployee).CurrentValues.SetValues(newEmployee); 9 context.SaveChanges(); 10 }
关键是第一行代码,意思就是把原来实体的值设置为新实体的值,你们能够查看CurrentValues.SetValues()这个方法的源代码,就能明白其中的道理。在执行查询的时候你们 能够打开SQLServer Profiler查看是否真的是部分更新了。若是该实体是一个新实体,该如何更新呢?仍是老办法让EntityFramework知道它的存在,把它的状态设置为UnChanged便可,综合两种状况,合并的代码以下:ip
public void Modify(Employee originalEmployee, Employee newEmployee) { if (context.Entry(originalEmployee).State != EntityState.Unchanged) context.Entry(originalEmployee).State = EntityState.Unchanged; context.Entry(originalEmployee).CurrentValues.SetValues(newEmployee); context.SaveChanges(); }
其实今天讲的都是new一新实体去更新数据库,关键是让EF 的Change Tracker跟踪新实体这样才能达到修改的目的,而这一切都是设置EntityState才行。
顺便提一下EntityState,它是一枚举类型,有Detached,Unchanged,Added,Deleted,Modified五个值分别表明:实体没被跟踪,啥操做对它无效;实体存在于数据库但还没被修改;实体被跟踪但不存在于数据库,实体存在于数据库而且标记为删除,SaveChanges操做将删除该实体;实体存在于数据库而且标记为修改,SaveChanges操做将修改该实体。get