当实体框架为与多对多关系表连接的两个数据库表(假设是Table1和Table2)生成ObjectContext时,它不会为外部参照表创建对象,而是选择关系两端的集合属性。所以在Table1上有EntityCollection<Table2> Table2s,在Table2上有EntityCollection<Table2> Table1s。在大多数情况下,这实际上是非常好的……
但是,在这个场景中,我有一个整数列表,表示应该在Table1.Table2s集合中的Table2行的数据库ID。
我看不到任何使用实体键设置集合的方法,所以我只能选择这些到ObjectContext中,这已经是一大堆无缘无故的工作了。我希望LINQ- to -Entities能够智能地推迟执行,并像我希望的那样在SQL服务器上执行所有这些操作(尽管我的Where使用的是Contains,它在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);
}这看起来很可笑,我知道这会迫使你进行很多不必要的评估。
有没有一种“正确的”,或者,也许是“不那么差劲”的方法来做到这一点?
发布于 2011-05-31 04:27:47
No EF不会延迟任何查询的执行。没有什么能像insert from select那样。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的条目之间的关系,而不从数据库加载任何记录。
是什么让一个接一个的添加记录变得“差劲”?你知道AddRange的好处是什么吗?典型集合中的AddRange扩展了内部数组的容量,只是将项目复制到扩展的数组中。EntityCollection不是典型的数组,它必须处理每个添加的实体。因此,即使会有一些AddRange,它也会在内部迭代项目并逐个处理它们。
https://stackoverflow.com/questions/6179378
复制相似问题