2016-03-29 124 views
1

使用EF和C#,我試圖做一個具有很多相關記錄的實體的克隆。我也想克隆相關記錄。頂級對象是Bid實體框架C# - 具有多對多關係的子對象克隆對象

class Bid 
    { 
      Collection<ItemGroup> ItemGroups {get;set;} 
      Collection<Evaluator> Evaluators {get;set;} 
    } 

兒童是ItemGroupsEvaluators。他們是多對多的。

class ItemGroup 
{ 
    Collection<Evaluator> Evaluators {get;set;} 
} 

Class Evaluator 
{ 
    Collection<ItemGroup> ItemGroups {get;set;} 
} 

我克隆Bid,和它的所有孩子,通過與

database.Bids.Add(bid); 
database.SaveChanges(); 

的問題是許多到查詢數據庫

Bid bid = dbContext.Bids.AsNoTracking().FirstOrDefault() 
        .Include(b => b.ItemGroups) 
        .Include(b => b.ItemGroups.Select(e => e.Evaluators)) 

並添加Bid回 - EvaluatorsItemGroups之間的多種關係。因爲他們的集合引用了彼此,所以當您添加Bid時,它會重新記錄這些記錄。

因此,克隆之前,我有一個出價:

Original Bid - 
Number of ItemGroups = 3 
Number of Evaluators = 2 

,並克隆後,我有新的出價,以:

New Bid - 
Number of ItemGroups = 3 
Number of Evaluators = 6 

這顯然是不正確。如何克隆這種關係而不用EF添加重複項?

問題是我的原始查詢?我嘗試了各種選擇,使用.Include()s,從Bid -> Evaluators -> Item Groups跟蹤,或者只是去Bid -> EvaluatorBid -> ItemGroup,但沒有什麼似乎讓我很想我想要的。任何和所有的幫助是非常感謝,請讓我知道,如果我可以提供一些澄清。提前致謝。

+0

在保存更改之前,您可能有更好的運氣來獲取啓用了跟蹤的實體並更改要添加的實體狀態。 https://msdn.microsoft.com/en-us/data/jj592676.aspx 我不認爲這會導致在你的例子中重複ItemGroups和Elevators,但我沒有測試過。 – James

+0

感謝您的意見。我不完全確定這就是我想要去的方式,但當克隆實體更向下時,會導致其他一些意想不到的行爲。 – kdeez

回答

0

那麼,這是我的超級解決方案,直到有人能告訴我一個更好的方式來做到這一點。基本上,我忽略了我的查詢Include()s中的多對多關係,僅查詢bid.ItemGroupsbid.Evaluators

我將這些添加爲正常,這給我一個Bid與適當數量的項目組和0個評估員,因爲ItemGroup - >評估者關係沒有建立,因爲我沒有查詢他們。

然後,在調用database.Bids.Add(bid)之後,我重新查詢原始出價以及它的Evaluator/ItemGroup關係,並使用名稱/ id的/任何可用標識符手動掛接所有Evaluator/ItemGroup引用。

List<Evaluator> originalEvals = db.Bids.Where(b => b.Id == entityId) 
       .Select(b => b.Evaluators) 
       .FirstOrDefault() 
       .ToList(); 
      foreach(Evaluator origEval in originalEvals) 
      { 
       db.Entry(origEval).Reference(e => e.ClientUser).Load(); 
       db.Entry(origEval).Collection(e => e.ItemGroups).Load(); 
      } 

      foreach (Evaluator newEval in bid.Evaluators) 
      { 
       Evaluator originalEval = originalEvals.Where(e => e.ClientUserId == newEval.ClientUserId).FirstOrDefault(); 

       foreach (ItemGroup ig in originalEval.ItemGroups) 
       { 
        newEval.ItemGroups.Add(bid.ItemGroups.Where(g => g.Name == ig.Name).FirstOrDefault()); 
       } 
      } 

低劣,但它的工作原理。