重新连接实体时,实体框架不会跟踪集合更改

时间:2012-01-31 08:59:05

标签: c# entity-framework mvvm change-tracking

我最近在MVVM WPF应用程序中使用了很多实体框架,但我遇到了一些问题。为了显示数据,我的视图模型使用了一个短暂的ObjectContext。这些视图模型将在长时间运行的过程中使用,因此我更喜欢使用短暂的ObjectContext来降低性能。

所以基本上它意味着我的实体在断开连接模式下使用。可以创建,查看,更新和删除这些entites。使用断开连接模式将更改保存回数据库没有问题。但我发现了一个特殊情况,即保存更改时没有出现SaveChanges()方法调用时出现的错误。当我尝试更新具有集合属性的实体时会发生这种情况。实体的标量属性保持不变,但集合上的更改不会反映到数据库中,就好像它无法在重新连接时跟踪这些更改一样。

以下是我的案例示例代码,我更改实体名称,然后将对象添加到其报告集合中。在SaveChanges()之后,只有客户端名称已反映在数据库中。

this.Client.Name = "Test Client";
this.Client.Reports.Add(new Report { Name = "Test Report" });

using (ReportCompositionEntities entities = new ReportCompositionEntities(this.connectionStringName))
{
    entities.Clients.ApplyCurrentValues(this.Client);
    entities.SaveChanges();
}

我是在做错事还是EF在重新附加实体时根本无法跟踪这种变化?

1 个答案:

答案 0 :(得分:8)

那是exactly what happens。没有更改跟踪,EF不知道导航属性中执行的更改。此外ApplyCurrentValues只能处理标量和复杂属性。不是导航属性。

在分离方案中修改关系时,必须手动告知EF在附加实体后修改的关系。您可以创建一些提供这些信息的自定义逻辑,并使用ObjectStateManager配置所有关系的状态,或者您只需使用数据库中的关系加载当前版本,并手动将更改从分离版本同步到加载的附加版本。

顺便说一下。我从来没有使用MVVM所以我不确定它在这种情况下是如何应用的,但是在MVP的情况下,如果它用于单个操作,你可以使用长生活上下文 - 例如编辑视图将由它自己的演示者处理它自己的上下文。只要视图将用于编辑单个实体/聚合,该上下文将存在=它将用于加载实体,并且相同的上下文将用于保存实体,因为在这种情况下编辑由相同的执行上下文执行并且属于单一工作单位。