实体框架C# - 克隆具有多对多关系的子对象

时间:2016-03-29 18:28:29

标签: c# asp.net-mvc entity-framework clone

使用EF和C#,我正在尝试克隆具有大量相关记录的实体。我也希望克隆相关记录。顶级对象是Bid

    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及其所有子项

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

并将Bid添加回

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

问题是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的{​​{1}},或者只是转到Bid -> Evaluators -> Item GroupsBid -> Evaluator,但似乎没有任何东西能让我得到我想要的东西。非常感谢任何和所有帮助,如果我能提供一些澄清,请告诉我。提前致谢。

1 个答案:

答案 0 :(得分:0)

嗯,这是我的超级解决方案,直到有人能告诉我更好的方法。基本上,我在查询Include()s中省略了多对多关系,仅查询bid.ItemGroupsbid.Evaluators

我将这些添加为正常,这为我提供了具有适当数量的项目组的Bid和0个评估者,作为ItemGroup - &gt;评估者关系没有建立,因为我没有查询它们。

然后,在调用database.Bids.Add(bid)之后,我重新查询原始出价及其Evaluator / ItemGroup关系,并使用names / 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());
                }
            }

Shitty,但它确实有效。

相关问题