2012-01-31 101 views
7

我最近在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是根本无法跟踪这种变化时重新连接实体?

回答

8

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

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

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

+0

真的很有趣的情况。现在EF不更新这些更改是有道理的,因为导航属性的实体也可以被另一个实体引用。创建新实体时没有问题,但可以在删除时发生并发问题。 在我的架构中,每个MVVM都是作为CRUD范例的单一可响应性。我将我的虚拟机移动到连接模式(处理过程由我的架构进行处理)和内存分析目前没有发现任何问题。时间会告诉,它实际上很容易回到断开模式。谢谢你的帮助。 – Ucodia 2012-01-31 10:02:29