2016-03-29 15 views
1

EFとC#を使用して、関連するレコードが多数存在するエンティティのクローンを作成しようとしています。私は関連するレコードもクローンしたいです。トップレベルのオブジェクトはBidです。 ItemGroupsEvaluatorsEntity Framework C# - 多対多リレーションを持つ子を持つオブジェクトのクローン

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

子供たち。彼らは多対多である。

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

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

データベース

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

と問題が多く-にある

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

バックでBidを追加することを照会することによって、私はBidのクローンを作成し、それがすべての子供たちです〜EvaluatorsItemGroupsの間の多くの関係彼らのコレクションはお互いを参照しているので、Bidを追加すると、レコードは複製されます。で、

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

と、クローンの後、私が持っている新しい入札:明らかに間違っている

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

だから、クローンの前に、私は、入札があります。 EFが重複を追加することなくこの関係をどのようにクローンしますか?

問題は私の元のクエリですか?私はBid -> Evaluators -> Item Groupsから.Include()sトレースを使用して、または単にBid -> EvaluatorBid -> ItemGroupに行くすべての種類のオプションを試してみましたが、何も私が望むものを得ることはできません。すべての助けが大変ありがとうございます。私が何らかの説明をすることができれば教えてください。前もって感謝します。

+0

トラッキングを有効にしてエンティティを取得し、変更を保存する前にエンティティの状態を追加することをお勧めします。 https://msdn.microsoft.com/en-us/data/jj592676.aspx これは、あなたの例でItemGroupsとElevatorsの複製につながるとは思わないが、これはテストしていない。 – James

+0

ありがとうございました。私はそれが私が行きたいと思う方法であるとは完全には分かっていません。それは、エンティティをグラフの下にもっと遠くにクローンすると、予期しない動作につながります。 – kdeez

答えて

0

誰かが私にそれをするより良い方法を教えることができるまで、まあ、ここに私のスーパージャンキーの解決策があります。基本的には、クエリInclude()sにmany-to-manyの関係を残し、bid.ItemGroupsbid.Evaluatorsのみを照会します。

通常のように追加します。適切な数のアイテムグループと0人​​の評価者が私にBidを与えますが、ItemGroup - > Evaluator関係は確立されませんでした。

database.Bids.Add(bid)を呼び出した後、私は元の入札を再クエリし、それはEvaluator/ItemGroupの関係であり、利用可能な識別子/識別子を使用してすべての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()); 
       } 
      } 

シティーですが、動作します。

関連する問題