假设已对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( );
}
谢谢
答案 0 :(得分:5)
我可以确认你的猜测。它没有这种方式。
当您使用实体作为参数调用Attach
时,EF会将实体添加到状态Unchanged
中的上下文中。基本上你用EF 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
将创建一个设置 all <的UPDATE语句/ em>当前属性值的列值。)