【问题标题】:How can I set a many-to-many EntityCollection in Entity Framework efficiently?如何有效地在实体框架中设置多对多 EntityCollection?
【发布时间】:2011-05-30 17:57:04
【问题描述】:

当 Entity Framework 为与多对多关系表连接的两个数据库表(比如说 Table1 和 Table2)生成 ObjectContext 时,它不会为外部参照表创建对象,而是选择在关系的任何一端。所以在 Table1 上你有 EntityCollection<Table2> Table2s,在 Table2 上你有 EntityCollection<Table2> Table1s。在大多数情况下,这实际上非常棒......

但是,在这种情况下,我有一个整数列表,表示应该在 Table1.Table2s 集合中的 Table2 行的数据库 ID。

我看不到使用实体键设置该集合的任何方法,因此我只能将它们选择到 ObjectContext 中,这已经是无缘无故要做的大量工作。我让自己希望 LINQ-to-Entities 能够智能地推迟执行并像我想要的那样在 SQL 服务器上执行它(尽管我的 Where 使用包含,它可能会或可能不会正确转换为 SQL 中的 IN())。所以我可以做到:

table1instance.Table2s.Clear();
var table2sToInclude = context.Table2s.Where(
  t => 
  listOfTable2DatabaseIds.Contains(t.Id));

但是没有EntityCollection<T>.AddRange(IEnumerable<T>)或任何东西,当然也没有IEnumerable<T>.ToEntityCollection<T>()扩展方法,所以我现在不知道如何处理这些结果。我能做的就是

foreach (var table2 in table2sToInclude)
{
  table1instance.Table2s.Add(table2);
}

这看起来很荒谬,我知道会强制进行很多不必要的评估。

有没有一种“正确的”,或者,也许是“不那么蹩脚”的方式来做到这一点?

【问题讨论】:

    标签: entity-framework-4 linq-to-entities many-to-many entitycollection addrange


    【解决方案1】:

    没有 EF 不会推迟任何查询执行。没有什么像从选择中插入一样。 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();
    }
    

    此代码在 Table1 的 id 为 123 的项目与 table2sToInclude 中的所有 Table2 项目之间创建关系,而不从数据库中加载任何单个记录。

    是什么让一条一条地添加记录“蹩脚”?你了解AddRange 的好处吗?典型集合中的AddRange 扩展了内部数组的容量,只是将项目复制到扩展数组。 EntityCollection 不是典型的数组,它必须处理每个添加的实体。因此,即使会有一些AddRange,它也会在内部迭代项目并逐个处理它们。

    【讨论】:

    • 这不是一一对应 AddRange,除了天真的希望在这种情况下调用 AddRange(如果存在)不会导致我不需要任何信息的 SELECT 语句(因为我已经有了 EntityKey Ids)实例化新的 Table2 对象并调用 Attach 的方法应该可以工作。谢谢
    猜你喜欢
    • 1970-01-01
    • 2013-03-11
    • 1970-01-01
    • 2012-10-29
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多