IQueryable 和计数

IQueryable and Count

我有以下内容:

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的fetch?或者它是否智能计数,知道它不需要执行 Select?

只要您保留它 IQueryable 而不是调用 ToList(),EF 就足够智能来优化查询并防止 Count() 查询上的任何实际 select。

Count() 变成了查询引擎知道的 Count() 的最佳实现。

数据库支持的查询引擎,如 Entity Framework 或 Linq2SQL 通常会使用导致 COUNT(*)COUNT(DISTINCT some_field) 或类似的东西用于 [=30] =]出品。

其他 linq 实现同样会尽可能聪明。例如,如果在实现 ICollectionICollection<T> 的对象上调用 linq-to-objects 将调用 Count getter 而不是枚举整个枚举。 20=]

在处理 Count() 的给定使用时,给定的查询引擎可能最终不得不循环遍历项目枚举,因为它无法找到更有效的方法。通常,您越是按照 Linq 的初始类型进行操作(例如,除非需要,否则不要调用 ToList(),如果您可以不这样做,则甚至不要调用 AsEnumerable())引擎会做得越好,尽管有时会有例外。