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

本文关键字:实体 集合 跟踪 框架 重新连接 | 更新日期: 2023-09-27 18:22:10

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

所以基本上,这意味着我的实体在断开连接的模式下被消耗。这些实体可以创建、查看、更新和删除。我使用断开连接模式将更改保存回数据库没有问题。但我发现了一个特殊的情况,在调用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在重新连接实体时无法跟踪这种变化?

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

这正是发生的事情。没有更改跟踪,EF不知道在导航属性中执行的更改。ApplyCurrentValues也只能处理标量和复数性质。不是导航属性。

在分离场景中修改关系时,您必须手动告知EF在附加实体后修改了哪些关系。您可以创建一些提供这些信息的自定义逻辑,并使用ObjectStateManager来配置所有关系的状态,也可以简单地从数据库中加载具有关系的当前版本,并手动同步从分离版本到加载的附加版本的更改。

Btw。我从未使用过MVVM,所以我不确定它在这种情况下如何应用,但在MVP的情况下,如果它用于单个操作,则可以使用长寿命上下文——例如,编辑视图将由其自己的演示者使用自己的上下文来处理。只要视图将用于编辑单个实体/聚合,该上下文就会一直存在=它将用于加载实体,并且相同的上下文将用于保存实体,因为在这种情况下,编辑由相同的执行上下文执行,并且属于单个工作单元。