1:如何new一个新实体去更新记录,而不是从数据库中查询一条记录来更新。
 2:如何在更新实体的同时,对导航属性的实体进行一系列的操作。
 3:如何用最简单的代码实现实体的部分更新。

new一个新实体去更新记录

EntityFramework有一个特点,你无须查询出一个记录,而是new一个新实体,然后对其进行删除或更新操作,只须提供实体的ID即可,如果ID不存在将会抛出异常。这样有助于提高性能,毕竟减少了一次数据库访问。要实现用一个新实体去更新记录,你得让EF的Change Tracker跟踪该实体,让它认为该实体就是从数据库中取出来的,只要让改该实体处于修改状态就行了,代码如下:

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操作就行了,代码如下:

技术图片
 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         
View Code

如果注释掉context.Customer.Add(entity)这行代码,将会抛出异常,这个是值得注意的地方。

3 实现实体的部分更新
以前好像在园子里有朋友讲过Entityframework实体部分更新的问题,就是用反射去遍历实体的属性,把需要修改的实体属性状态设置为Modified,这样也可以达到目的,但是这样写的代码有点多,而且对Entityframework的特性没有充分的利用,其实很简单两行代码就搞定:

技术图片
 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即可,综合两种情况,合并的代码如下:

技术图片
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操作将修改该实体。

 

c#+entityframework编程方式详细之codefirst数据迁移

在前几篇的C#+EntityFramework编程方式中介绍了C#+EntityFramework编程方式CodeFirst,ModelFirst以及DtatabaseFirst等编程方式,其中ModelFirst以及DtatabaseFirst中,如果实体类(ModelFirst)或者数据库(DtatabaseFirst)变化了,那么就需要数据库(ModelFirst)或... 查看详情

EntityFramework CodeFirst 数据库不更新

】EntityFrameworkCodeFirst数据库不更新【英文标题】:EntityFrameworkCodeFirstDatabasedoesn\'tupdate【发布时间】:2012-10-0713:07:55【问题描述】:一天前,我开始在简单的Windows窗体项目(C#)中使用实体框架CodeFirst。我创建了两个模型:[Table("Save... 查看详情

《entityframework6recipes》中文翻译系列(12)-----第三章查询之使用sql语句(转)

3-2使用原生SQL语句更新问题  你想在实体框架中使用原生的SQL语句,来更新底层数据存储。解决方案  假设你有一张如图3-2所示的Payment数据库表,使用实体框架设计器工具创建了一个如图3-2所示的模型。图3-2Payment表,包含一... 查看详情

浅谈缓存最终一致性的解决方案(代码片段)

...工程师到底是更新缓存还是删除缓存? 到底是先更新数据库,再删除缓存,还是先删除缓存,再更新数据库?或采用延迟队列。显而易见的是,无论这个值如何预估,都很难和读请求的完成时间点准确衔接,这也是延时双删被... 查看详情

浅谈数据结构之线性表顺序存储

   首先,数据结构是由某一数据元素集合及该集合中所有数据元素之间的关系组成。具体来说,数据结构应当包含三方面的内容:(1).数据的逻辑结构;(2).数据的存储结构;(3).对数据所施加的操作。而数据的存储结构形式... 查看详情

利用entityframework修改sql数据库中数据

利用entityframework修改SQL数据库中数据时,是不是必须把表中所有字段都修改一下,否则该条数据其他字段自动变为空?如何修改表中某行的单个字段,而其他值不受影想。例如student中有字段ID,Name,Sex,Age,现在若用entity至修改name值... 查看详情

entityframework使用entitystate和attach来保存数据变化以及更新实体的个别字段(代码片段)

在使用EntityFramework作为ORM来存取数据的过程中,最常规的操作就是对数据对象的更新。本文将会包含如何AttachEntity到一个数据Context中,以及如何使用EntityState字段状态来保存数据变化。文本参考了如下两篇文章:https://msdn.microsof... 查看详情

EntityFramework 更新 6.0 到 6.1.3 后仍然没有异步方法?

】EntityFramework更新6.0到6.1.3后仍然没有异步方法?【英文标题】:StillnoasyncmethodsafterEntityFrameworkupdate6.0to6.1.3?【发布时间】:2016-07-2322:35:02【问题描述】:我有一个通过EntityFramework6.0与数据库通信的ASP.NETMVC4。DbContext是使用具有数... 查看详情

如何处理arp的攻击技巧

...。如:X向Y发送一个自己伪造的ARP应答,而这个应答中的数据发送方IP地址是192.168.1.3(Z的IP地址),MAC地址 查看详情

浅谈数据结构之顺序栈

...插入与删除的一端称为栈顶,另一端称为栈底,不含任何数据元素的称为空栈。栈的插入操作,叫作进栈,也叫压栈、入栈,类似于子弹入弹夹;栈的删除操作,叫作出栈,也叫弹栈,如同弹夹中的子弹出夹。注意:栈的定义中... 查看详情

浅谈软件测试之数据校验

注明:DBCheck即数据库数据校验;一.为什么需要DBCheck?你同学去年向你借了一万大洋,今天你打电话想他还钱给你,老同学很大方的给你说马上给你打到银行卡上。一会儿,回电话给你说,钱已经全部打到你银行卡了,让你等会儿... 查看详情

《entityframework6recipes》翻译系列-----第一章开始使用实体框架之历史和框架简述(转)

微软的EntityFramework受到越来越多人的关注和使用,EntityFramework7.0版本也即将发行。虽然已经开源,可遗憾的是,国内没有关于它的书籍,更不用说好书了,可能是因为EF版本更新太快,没人愿意去花时间翻译国外关于EF的书籍。... 查看详情

浅谈数据结构之链队列

...介绍一下循环队列。循环队列是为了避免数组插入与删除数据时需要移动数 查看详情

entityframework数据库字段更改而实体不随即更新

我用了从数据库更新模型=》刷新,也用了从数据库更新模型=>添加实体都没有变化!报错!错误575错误11009:未映射属性“DifficultyID”。D:\TFEdu.AskAnswer\TFEdu.AskAnswer\AskAnswer.Models\AskAnswer.edmx72111AskAnswer.Models错误576正在... 查看详情

浅谈数据库之存储过程(代码片段)

...储过程的能力大大增强了SQL语言的功能和灵活性。可保证数据的安全性和完整性。通过存储过程可以使没有权限的用户做控制之下间接地存储数据库,从而保证数据的安全。存储过程可以使相关的动作一起发 查看详情

浅谈数据结构之链栈

  栈的链式存储结构,我们一般简称为“链栈”。由于单链表有头指针,而栈顶指针也是必须要有的,所以我们通常把栈顶放在单链表的头部,有了栈顶在头部,单链表中比较常用的头结点就失去了意义。通常对于链栈来说,... 查看详情

idea常用的小技巧汇总,java新手上路必备,快上车!(持续更新)

目录一、下载安装激活IDEA二、IDEA安装目录结构说明三、快速入门之HelloWord四、新建package和class五、IDEA面板概览六、IDEA常用设置6.1随心所欲之自定义背景与字体大小设置6.2开发必备之代码提示忽略大小写6.3开发必备之设置自动... 查看详情

浅谈数据结构之线性表链式存储

...结构,它的特点是:用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。这就意味着,这些数据可以存在内存中未被占用的任意位置上,即当线性表进行插入与删除时就不需要移动大... 查看详情