IQueryable和Count

时间:2015-04-02 15:28:24

标签: c# linq iqueryable

我有以下内容:

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

2 个答案:

答案 0 :(得分:4)

Count()已成为查询引擎了解的Count()的最佳实现。

像Entity Framework或Linq2SQL这样的数据库支持的查询引擎通常会使用导致COUNT(*)COUNT(DISTINCT some_field)或类似内容的东西在SQL生成中使用。

其他linq实现同样会尝试尽可能聪明。例如,如果在实现CountICollection的对象上调用它,则linq-to-objects将调用ICollection<T> getter而不是枚举整个枚举。

在处理给定Count()的使用时,给定的查询引擎可能最终必须循环遍历项目的枚举,因为它无法找出更有效的任何内容。通常情况下,你在Linq的初始类型上保留的东西越多(例如,除非你需要,否则不要打电话给ToList(),如果你不能这样做,你甚至可以AsEnumerable())引擎会做得越好,但有时会有例外。

答案 1 :(得分:1)

只要您保留IQueryable而不是调用ToList(),EF就足够聪明,可以优化查询并阻止对Count()查询进行任何实际选择。