2011-12-07 88 views
3

我想附加一個對象樹到我通過WCF服務調用提供的實體框架上下文。有問題的對象具有子項目集合,並且每個子項目都具有屬於另一個跟蹤對象類型的屬性。但是,這些最後的項目只有一小部分,所以大部分收集項目都會共享它們。像這樣的事情(除了,很明顯,與EntityObjects):實體框架附加()對象樹與共享對象

public class Product 
{ 
    public int Id; 
    public string Name; 
    public decimal Cost; 
} 

public class Order 
{ 
    public int Id; 
    public List<Detail> details; 
} 

public class Detail 
{ 
    public int Id; 
    public Product Product; 
    public int Quantity; 
} 

每當我有了同樣的產品不止一個詳細的訂單,實體框架,因爲它試圖連接的多個拷貝過程中附加抱怨相同的產品密鑰。這些信息來自WCF ServiceOperation,因此它將作爲Product的離散實例進行反序列化,即使在客戶端它們是一組共享對象。

有什麼辦法可以告訴EF對象上下文重新使用被追蹤的實體,當Attach發生時?請注意,我不直接附加產品,所以諸如檢查TryGetObjectStateEntry這樣的技巧將不起作用。

有什麼建議嗎?

編輯:

我遇到對自我跟蹤實體下面的文章(我已經切換到使用),其中包括一對夫婦可以用來替代Slauma的回答客戶端選項跑,這將保留服務器端的協調代碼。 (自追蹤實體無需使用附加(),但重複鍵的問題依然存在。)

http://blogs.msdn.com/b/diego/archive/2010/10/06/self-tracking-entities-applychanges-and-duplicate-entities.aspx

回答

1

沒有,也沒有辦法。你基本上需要使每個鍵的對象引用獨特的你連接之前,是這樣的:

void PrepareForAttach(Order order) 
{ 
    var dict = new Dictionary<int, Product>(); 
    foreach (var detail in order.Details) 
    { 
     Product firstProduct; 
     if (dict.TryGetValue(detail.Product.Id, out firstProduct)) 
      detail.Product = firstProduct; 
     else 
      dict.Add(detail.Product.Id, detail.Product); 
    } 
} 

EF地圖密鑰身份對象引用身份,它不允許有兩個或多個對象以相同的密鑰上下文。它也沒有一個功能可以使參考文獻具有獨特性,這意味着您可以使用與正確產品相同的密鑰來選擇您的某個產品。 (你可能有兩個產品具有相同的密鑰但是具有不同的其他屬性,那麼這個密鑰的「正確」產品是什麼?EF拒絕決定(如果屬性的值都相同,則不會根據屬性比較屬性),並選擇簡單和安全的模式:拋出異常。)