我有以下内容:
IQueryable<ViewAccountEntry> viewAccountEntries = db.AccountEntries
.Where(x => x.DEntryID == 0)
.Select(x => new ViewAccountEntry()
{
AccountEntry = x,
DAccountEntries = db.AccountEntries
.Where(y => y.DEntryID == 0
&& y.Amount == -x.Amount
&& y.DateEntry == x.DateEntry)
.ToList()
});
Pages = new PageInfo(viewAccountEntries.Count(), page);
ViewAccountEntries = viewAccountEntries
.OrderBy(x => x.AccountEntry.DateEntry)
.Skip(Pages.ItemsSkipped)
.Take(Pages.ItemsPerPage)
.ToList();
在第一个Select()
内创建一个包含第二个列表的对象。
执行.Count()
时,它是否执行第二个Select
的提取?或者它是否智能计数,知道它不需要执行Select
?
答案 0 :(得分:4)
Count()
已成为查询引擎了解的Count()
的最佳实现。
像Entity Framework或Linq2SQL这样的数据库支持的查询引擎通常会使用导致COUNT(*)
,COUNT(DISTINCT some_field)
或类似内容的东西在SQL生成中使用。
其他linq实现同样会尝试尽可能聪明。例如,如果在实现Count
或ICollection
的对象上调用它,则linq-to-objects将调用ICollection<T>
getter而不是枚举整个枚举。
在处理给定Count()
的使用时,给定的查询引擎可能最终必须循环遍历项目的枚举,因为它无法找出更有效的任何内容。通常情况下,你在Linq的初始类型上保留的东西越多(例如,除非你需要,否则不要打电话给ToList()
,如果你不能这样做,你甚至可以AsEnumerable()
)引擎会做得越好,但有时会有例外。
答案 1 :(得分:1)
只要您保留IQueryable
而不是调用ToList()
,EF就足够聪明,可以优化查询并阻止对Count()
查询进行任何实际选择。