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( );
}

谢谢

4

1 回答 1

5

我可以证实你的猜测。这种方式行不通。

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

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

如果附加实体的属性值与传递给ApplyCurrentValuesEF 的对象的属性值不同,则将该属性标记为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 语句,将所有列值设置为当前属性值)。

于 2013-04-13T12:13:43.580 回答