关于EF4与NHibernate相比,我听到的少数有效投诉之一就是EF4在处理延迟加载的集合方面很差.例如,在一个延迟加载的集合中,如果我说:
if (MyAccount.Orders.Count() > 0) ;
Run Code Online (Sandbox Code Playgroud)
EF将整个系列拉下来(如果还没有),而NH将足够智能发出一个 select count(*)
NH还有一些很好的批量提取来帮助解决这个select n + 1问题.据我了解,最接近的EF4可以使用Include方法.
EF团队是否有任何迹象表明这将在下一次迭代中修复?我知道他们在POCO上很努力,但这似乎是一个受欢迎的解决方案.
Lad*_*nka 13
你描述的不是N + 1问题.N + 1问题的例子在这里.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)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
这很容易解决:
// Eager load all Orders and their items in single query
foreach(var order in context.Accounts.Include("Orders.Items").Where(...))
{
...
}
Run Code Online (Sandbox Code Playgroud)
你的例子看起来对我有用.您有一个公开的集合,IEnumerable并对其执行Count操作.集合是延迟加载的,计数在内存中执行.将Linq查询转换为SQL的功能仅适用于IQueryable表示查询的表达式树.但是IQueryable表示query =每次访问意味着在DB中执行新的执行,例如,检查Count in循环将在每次迭代中执行DB查询.
所以它更多的是关于动态代理的实现.
在使用代码优先CTP5(最终版本将被称为EF 4.1)时,已经可以计算相关实体而不加载它们DbContext,ObjectContext而不是直接与集合交互.您必须使用以下内容:
int count = context.Entry(myAccount).Collection(a => a.Orders).Query().Count();
Run Code Online (Sandbox Code Playgroud)
Query方法返回准备好了IQueryable,如果你使用延迟加载可能是EF运行的,但你可以进一步修改查询 - 这里我用过Count.
| 归档时间: |
|
| 查看次数: |
10944 次 |
| 最近记录: |