如何在Entity Framework中有效设置多对多EntityCollection?

问题描述

| 当Entity Framework为与多对多关系表连接的两个数据库表(例如Table1和Table2)生成ObjectContext时,它不会为外部参照表创建对象,而是选择集合属性在关系的任何一端。因此,在表1上您有
EntityCollection<Table2> Table2s
,在表2上您有
EntityCollection<Table2> Table1s
。在大多数情况下,这实际上非常好... 但是,在这种情况下,我有一个整数列表,这些整数表示应该在Table1.Table2s集合中的Table2行的数据库ID。 我看不到任何使用实体键来设置该集合的方法,因此我一直坚持将它们选择到ObjectContext中,而这已经是无缘无故要做的大量工作。我让自己希望LINQ-to-Entities能够智能地推迟执行并像我希望的那样在sql Server上执行所有操作(尽管我的Where使用Contains,在sql中可能正确地转换为IN())。因此,我可以走得更远:
table1instance.Table2s.Clear();
var table2sToInclude = context.Table2s.Where(
  t => 
  listofTable2DatabaseIds.Contains(t.Id));
但是没有
EntityCollection<T>.AddRange(IEnumerable<T>)
或任何东西,当然也没有so4ѭ扩展方法,所以我现在不知道如何处理这些结果。我所能做的就是
foreach (var table2 in table2sToInclude)
{
  table1instance.Table2s.Add(table2);
}
这似乎很荒谬,我知道这将迫使许多不必要的评估。 是否有一种“正确”的方法,或者也许是一种“较少la脚”的方法?     

解决方法

        没有EF不会推迟任何查询的执行。没有像select中的insert这样的东西。 Linq-to-entities只是查询语言,查询的责任是执行。它与EF本身提供的持久性功能严格分开。 如果要在table1的现有项目和table2的现有项目之间创建关系,可以使用如下代码:
using (var ctx = new YourContext())
{
    var table1 = new Table1 { Id = 123 };
    ctx.Table1s.Attach(table1);

    foreach (var table2 in table2sToInclude.Select(id => new Table2 { Id = id }))
    {
        ctx.Table2s.Attach(table2);
        order.Table2s.Add(table2);
    }
    ctx.SaveChanges();
}
这段代码在ID为123的Table1 \项与table2sToInclude中所有Table2 \的项之间建立关系,而无需从数据库中加载任何单个记录。 是什么使得一张一张“ lam”地添加记录?你知道ѭ7的好处是什么吗?典型集合中的“ 7”扩展了内部阵列的容量,并且仅将项目复制到扩展阵列。 “ 9”不是典型的数组,它必须处理每个添加的实体。因此,即使会有一些“ 7”,它也会在内部迭代项目并逐个处理它们。