2011-08-03 37 views
1

我有以下基於EntityObject-EF模型(在這裏寫成領域保持代碼更加屬性):EF4保存複雜的分離對象圖

Booking 
{ 
    int BookingID; 
    EntityCollection<BookingCustomer> BookingCustomers; 
    string Notes; 
} 

BookingCustomer 
{ 
    Customer Customer; 
    Booking Booking; 
    int CustomerID; 
    int BookingID; 
    string Notes; 
} 

Customer 
{ 
    int CustomerID; 
    string Name; 
} 

我加載在分離的方式對象圖:

Booking existingBooking; 
using(MyContext ctx = new MyContext()) 
{ 
    ctx.Bookings.MergeOption = MergeOption.NoTracking; 
    ctx.BookingCustomers.MergeOption = MergeOption.NoTracking; 
    ctx.Customers.MergeOption = MergeOption.NoTracking; 
    existingBooking = ctx.Bookings 
     .Include("BookingCustomers") 
     .Include("BookingCustomers.Customer") 
     .First(); 
} 

修改預訂和客戶數據:

existingBooking.Notes = "Modified"; 
existingBooking.BookingCustomers.First().Name += " Edited"; 

保存它:

using(MyContext ctx = new MyContext()) 
{ 
     ctx.Bookings.Attach(existingBooking); 
     ctx.ObjectStateManager.GetObjectStateEntry(existingBooking).SetModified(); 
     ctx.Refresh(RefreshMode.ClientWins, existingBooking);  
     ctx.SaveChanges(); 
} 

我得到創建(而不是現有記錄更新)一個客戶記錄。

我也試過這樣:行ctx.Customers.Attach(existingBooking.BookingCustomers.First());

using(MyContext ctx = new MyContext()) 
{ 
    ctx.Customers.Attach(existingBooking.BookingCustomers.First()); 
    ctx.ObjectStateManager.GetObjectStateEntry(existingBooking.BookingCustomers.First()).SetModified(); 
    ctx.Refresh(RefreshMode.ClientWins, existingBooking.BookingCustomers.First()); 

    ctx.Bookings.Attach(existingBooking); 
    ctx.ObjectStateManager.GetObjectStateEntry(existingBooking).SetModified(); 
    ctx.Refresh(RefreshMode.ClientWins, existingBooking);  
    ctx.SaveChanges(); 
} 

,但得到的異常:

System.InvalidOperationException: A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship. 

我怎樣才能使它發揮作用?

+0

那你最終做來解決這個問題? –

+0

我結束了使用附加對象,以便上下文從加載保存到保存。 – Muxa

回答

1

這是不是清爽。如果修改處於分離狀態的圖形,EF無法找到您所做的更改。您必須手動設置每個modified entity or relation的狀態。 Attach會把整個圖形中Unchanged狀態和ChangeObjectState影響圖僅單一實體。

您發現的最簡單的方法是在保存時重新加載整個圖形並手動合併更改附圖。特別是如果你想刪除一些關係/實體或做複雜的操作與多對多關係,這將是方便的。

1

拉吉斯拉夫是正確的。然而,還有一個選項需要考慮哪個可以解決這個問題,並且仍然允許您保留detatched模型 - 自我跟蹤POCO。有一個T4模板(它或者用VS2010捆綁或可下載),它允許一個對象圖來跟蹤其狀態(這包括添加/刪除對象轉換成圖形,以及如何處理的對象屬性已經改變),這樣你可以重新附加做出修改的圖形; EF4將找出這些變化並將它們應用於對象狀態管理器。

+0

我已經嘗試了自我跟蹤的POCO,並且實際上得到了相同的結果 - 每次保存預訂時都會創建新客戶。 – Muxa

+0

事情不對。你可以在將它附加到對象上下文之前查看對象的狀態 - 它應該被標記爲已修改。 –