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

本文关键字:实体 分离 框架 保存 | 更新日期: 2023-09-27 18:08:49

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

谢谢

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

我可以证实你的猜测。这是行不通的。

当你用一个实体作为参数调用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语句,将所有列的值设置为当前属性值)。