实体框架 - 保存对分离实体所做的更改

时间:2013-04-12 21:24:32

标签: c# entity-framework entities

假设已对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( );
}

谢谢

1 个答案:

答案 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>当前属性值的列值。)