2013-04-12 142 views
2

说在EF 4中对分离实体进行了更改。如果我们想在重新连接实体时保存这些更改,是否可以使用ApplyCurrentValues查询数据库以获取原始实体?我不这么认为,但我希望有人确认。实体框架 - 保存对分离实体所做的更改

using (var ctx = new BAEntities()) 
{ 
var firstCust = (from c in ctx.Contacts select c).First(); 
Console.WriteLine(firstCust.FirstName); 
ctx.Contacts.Detach(firstCust); 

firstCust.FirstName = "Modified Value"; 
ctx.Contacts.Attach(firstCust); 
ctx.ApplyCurrentValues("Contacts", firstCust);//Does not work 

//ctx.ObjectStateManager.ChangeObjectState(firstCust, EntityState.Modified); //Works with that line 
      ctx.SaveChanges(); 
} 

谢谢

回答

5

我可以证实你的猜测。它不以这种方式工作。

当您使用实体作为参数调用Attach时,EF将该实体添加到状态为Unchanged的上下文中。基本上,您通过Attach告诉EF,实体当时具有的所有属性值都代表数据库中的当前值。

ApplyCurrentValues是一种“自动映射器”,它只是将您传入的对象的属性值复制到具有相同密钥的附加实体中,即ApplyCurrentValues。此副本基于属性名称发生。

如果附属实体的属性值与您传入的对象的属性值不同ApplyCurrentValues EF将属性标记为Modified。如果不是状态为Unchanged。很明显,在你的程序中,所有的财产状态都会保持不变,没有任何东西会被写入数据库。

从理论上讲,你可以做疯狂的事情,使其工作,如:

firstCust.FirstName = "Modified Value"; 
var dummyCust = new Contact { FirstName = "UnlikelyNameThatWillNeverOccur" }; 
ctx.Contacts.Attach(dummyCust); 
ctx.ApplyCurrentValues("Contacts", firstCust); 

这里FirstName属性将被标记为Modified。但是您必须为每个属性执行此操作,结果与将整个实体的状态设置为Modified的结果相同,如同在注释代码行中所做的那样。

您可以通过方式单一属性设置为Modified

ctx.Contacts.Attach(firstCust); 
ctx.ObjectStateManager.GetObjectStateEntry(firstCust) 
    .SetModifiedProperty("FirstName"); 

这将发送一个UPDATE语句仅设置FirstName列值的数据库(而整个实体的状态设置为Modified将创建UPDATE语句,将所有列值设置为当前属性值)。