2011-05-19 37 views
2

我有一個ASP.NET MVC 3應用程序,使用實體框架4來處理數據訪問。ASP.NET MVC3父子關係和實體框架,如何更新孩子?

我的視圖模型對象的結構是這樣的:

public class OrderViewModel 
{ 
    public int Id { get; set; } 
/* ... */ 
    public List<OrderLineItemViewModel> LineItems { get; set; } 
} 

public class OrderLineItemViewModel 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

而且,我的實體框架模型是這樣的:

public class Order 
{ 
    public int Id { get; set; } 
/* ... */ 
    public List<OrderLineItem> LineItems { get; set; } 
} 

public class OrderLineItem 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

,我用的是如何處理編輯掙扎的事情現有訂單。我的控制器函數將父視圖模型轉換爲一個Order對象,並將子對象(OrderLineItemViewModel)轉換爲實體模型(OrderLineItem)。但是,在將實體附加到ObjectContext時,它會丟失哪些行項目已更改,添加或刪除的狀態。

我發現地址父/子關係的所有示例似乎都提倡不對兒童進行級聯更新,寧願使用單獨的Controller Action和View來更新子集合。但是,我試圖讓編輯發生爲一個原子操作......當用戶點擊「編輯順序」來提交更改時,我希望更新父項字段,以及處理任何新的/刪除/修改的子項。 ..

在從視圖模型轉換時,處理實體框架中的子對象的更改跟蹤的最佳方法是什麼?

我已經嘗試添加一個IsNew,IsDirty和IsDeleted到ViewModel和模型,然後調用每個孩子(附加,刪除或添加)適當的功能,但我收到錯誤時試圖添加說孩子alreadys存在於UnChanged狀態的ObjectStateManager中...

謝謝!

回答

2

您必須確實以某種方式告訴EF發生了什麼變化,添加了什麼以及刪除了什麼。有兩種方法:

  • 創建一個從您的視圖模型您OrderOrderLinesAttachOrder實例的上下文。之後,您必須更改每個實體的狀態(context.ObjectStateManager.ChangeObjectState)。
  • 首先從數據庫加載整個OrderOrderLines,然後將視圖模型中的更改合併到附加實體圖 - 這就是我使用的。

更復雜的描述在another answer。當您使用多對多或一對多關係來處理相關實體可以更改父對象時,這種情況會變得更糟。

+0

第二個方法,代碼示例(帶的DbContext雖然),只是作爲附加參考:http://stackoverflow.com/q/5538974/270591 – Slauma 2011-05-19 17:18:08

+0

謝謝!這證實了我的想法......我本來希望EF能阻止我這樣做國家管理。 – vt100 2011-05-19 18:56:04

0

只有兩種方法可以找出更改的內容。

  1. 您可以使用javascript來跟蹤客戶端的更改。這意味着當你發佈表單時,你的javascript會攔截帖子並將其與它加載屏幕的原始數據進行比較。
  2. 您可以遍歷子對象並將它們與控制器中的對象進行比較。如果有差異,你可以保存它們。

有一種方法可以保存,而不必知道哪些變化可能會更有效一些。然而,這需要創建一個自定義查詢和使用TSQL的MERGE:

http://technet.microsoft.com/en-us/library/bb510625.aspx