entity-framework - 在下一个 Entity Framework 中选择 N+1

标签 entity-framework

我听到的关于 EF4 与 NHibernate 的少数有效提示之一是,EF4 无法处理延迟加载的集合。例如,在延迟加载的集合上,如果我说:

if (MyAccount.Orders.Count() > 0) ;

EF 将拉下整个集合(如果还没有),而 NH 将足够聪明地发出 select count(*)
NH 也有一些不错的批量提取来帮助处理 select n + 1问题。据我了解,最接近的 EF4 是使用 Include 方法。

EF 团队是否有任何迹象表明这将在下一次迭代中修复?我知道他们正在努力研究 POCO,但这似乎是一个流行的修复方法。

最佳答案

你描述的不是N+1问题。 N+1 问题的例子是 here . N+1 意味着您执行 N+1 个选择而不是一个(或两个)。在您的示例中,它很可能意味着:

// Lazy loads all N Orders in single select
foreach(var order in MyAccount.Orders)
{
  // Lazy loads all Items for single order => executed N times
  foreach(var orderItem in order.Items)
  {
     ...
  }
}
这很容易解决:
// Eager load all Orders and their items in single query
foreach(var order in context.Accounts.Include("Orders.Items").Where(...))
{
 ...
}
你的例子对我来说是有效的。你有一个公开的集合 IEnumerable然后你执行 Count对其进行操作。 Collection 是延迟加载的,count 在内存中执行。将 Linq 查询转换为 SQL 的功能仅在 IQueryable 上可用用表示查询的表达式树。但是IQueryable表示查询 = 每次访问意味着在 DB 中执行新的操作,因此例如在循环中检查 Count 将在每次迭代中执行 DB 查询。
所以更多的是关于动态代理的实现。

使用 DbContext 时,在 Code-first CTP5(最终版本将称为 EF 4.1)中已经可以计算相关实体而不加载它们。而不是 ObjectContext但不是通过与收藏的直接互动。你将不得不使用类似的东西:
int count = context.Entry(myAccount).Collection(a => a.Orders).Query().Count();
Query方法返回准备好的 IQueryable如果您使用延迟加载,这可能是 EF 运行的内容,但您可以进一步修改查询 - 在这里我使用了 Count .

关于entity-framework - 在下一个 Entity Framework 中选择 N+1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5070013/

相关文章:

c# - 两个相似的 LINQ 查询,生成的 SQL 完全不同

c# - .net 中的存储库模式和继承

c# - 使用 xbuild 和 mono 时未嵌入 Entity Framework 元数据工件

.net - 使用复合键在模型中创建关系会引发 "Property is part of key and can' t be modded”异常

c# - 为什么 EF 获取所有记录,然后通过 PK 再次获取所有记录

asp.net-mvc - 找不到类型或命名空间名称 'DbContext'

c# - System.ComponentModel.DataAnnotations.Schema 命名空间冲突

c# - 如何使用 Entity Framework 制作查询字符串

c# - 十进制算术溢出

c# - 有关如何教程(WPF/Entity Framework/ObservableCollections)的问题