2011-04-28 62 views
0

我正在使用實體框架4,WCF和Silverlight。用現有子項添加新對象導致重複

我有一個訂單到產品的多對多關係。

[Order]*--*[Product] 

使用Model首先,Entity Framework會自動爲我創建連接表。當我在服務器端創建所有東西時,事情就可以正常工作。使用Silverlight時會出現問題。

我帶回產品列表並將它們顯示在屏幕上。用戶創建一個新訂單,並選擇應與訂單分開的產品。然後它被提交給WCF。

var order = new order(); 
order.CustomerName = customerTextBox.Text; 
... 
order.Products = new ObservableCollection<Product>(); 

foreach (var product in selectedProducts) 
{ 
    order.Products.Add(product); 
} 
var proxy = new OrderService(); 
proxy.CreateOrderAsync(order); 

在服務器端,這只是一個很簡單的add方法

var db = new Model1Container(); 
db.Products.AddObject(order); 
db.SaveChanges(); 

然而奇怪的事情發生了。保存時,數據庫中的幾乎所有內容都會被重複幾次。我的猜測是因爲實體框架幾次遍歷循環鏈接。

我試着將它改爲db.Categories.Attatch(order)。但這導致沒有任何保存。 我也嘗試循環和手動附加每個產品在保存訂單之前。但是,這會導致拋出異常,並指出對象已經連接到上下文。


編輯:這樣做停止的產品被複制。但是表中的所有訂單仍然是重複的。必須遍歷所有的關係嗎?

db.Orders.AddObject(order); 
db.ObjectStateManager.ChangeObjectState(order, EntityState.Added); 

foreach (var product in order.Products) 
{ 
    db.ObjectStateManager.ChangeObjectState(product, EntityState.Unchanged); 
} 

db.SaveChanges(); 

回答

1

嘗試此代替:

var db = new Model1Container(); 
db.Categories.Attach(order); 
db.ObjectStateManager.ChangeObjectState(order, EntityState.Added); 
db.SaveChanges(); 

的問題是,AddObject插入在對象圖每未跟蹤實體。在使用EF時,您必須明確說出EF發生了什麼變化。如果您允許用戶修改訂單,您仍然會have problems

+0

沒有任何效果。訂單和產品表中的所有內容仍然是重複的 – 2011-04-28 13:36:08

+0

我採納了您的建議,並對其進行了擴展。現在產品不重複,但表格中的所有訂單仍然是重複的。 db.Orders.AddObject(order); db.ObjectStateManager.ChangeObjectState(order,EntityState.Added); (product,order.Products) { db.ObjectStateManager.ChangeObjectState(product,EntityState.Unchanged); } db.SaveChanges(); – 2011-04-28 13:59:03

+0

你是什麼意思的所有命令?你正在插入單個訂單,不是嗎? – 2011-04-28 14:08:09

0

您使用的是WCF RIA嗎?如果不是,你應該考慮它。 DomainServices會帶來很多痛苦。

另外,你爲什麼不創建一個'order_position'表?像這樣,你不再有多對多的關係。一個訂單隻有一個訂單,只有一個產品。您也可以爲其分配一個價格,這使得它可以存儲在統計數據中(當您想要查看您爲產品A創造了多少資金,但您幾次更改了數據庫中的價格時會發生什麼?)。

+0

我在所有其他場景中使用RIA。在這種情況下,我需要使用它。另外Entity Framework已經在封面下創建了連接表,所以它不是*真正的多對多關係。是的,我知道連接表中沒有數量等的限制。爲簡化起見,我將表格重命名爲產品/訂單。 – 2011-04-28 13:36:33

+0

好的。無論如何,我會使用order_position表的原因是這樣的問題變得非常簡單,而且您的程序可以保持可擴展性。你只需要: Context = new Model1DomainContext(); order = new order(); Context.orders.Add(order); ... foreach(var product in products) { product.Order = order; Context.products.Add(order); } var submitOperation = Context.SubmitChanges(); submitOperation.Completed + = ... – LueTm 2011-04-28 13:39:48

+0

這實際上是一個非常具體的,一次性的示例,向人們展示它可以完成的方式,然後向他們展示使用Entity Framework執行此操作的簡單方法。 – 2011-04-28 13:43:18

相關問題