2012-01-31 105 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