【问题标题】:IQueryable and CountIQueryable 和 Count
【发布时间】:2015-04-02 15:28:23
【问题描述】:

我有以下:

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

【问题讨论】:

  • 记录正在执行的实际 SQL(如果仅此一项并不能为您提供答案,请分析数据库)并自己找出答案。
  • 也不知道该怎么做。
  • 那么现在是学习的好时机。您应该检查您曾经编写过的大多数 LINQ 查询的 SQL(至少是任何复杂的查询),以验证您的工作并确保在幕后没有发生任何奇怪的事情。至于如何,这将根据查询提供程序而有所不同,但每个都将公开一种记录它的方法。在数据库端查看查询的详细执行计划也是如此;查找您的特定数据库。
  • 但是,我意识到我可以创建第一个没有选择的 IQueryable,然后再添加选择部分。感谢您的帮助。
  • 我在 Visual Studio 下使用 MDF。

标签: c# linq iqueryable


【解决方案1】:

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

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

其他 linq 实现将类似地尝试尽可能聪明。例如,如果在实现 ICollectionICollection&lt;T&gt; 的对象上调用 linq-to-objects 将调用 Count getter,而不是枚举整个枚举。

在处理Count() 的给定使用时,给定的查询引擎可能最终不得不循环遍历项目的枚举,因为它无法找出更有效的方法。通常,您根据 Linq 的初始类型保留的内容越多(例如,除非您需要,否则不要调用 ToList(),或者如果您可以不这样做的话,甚至不要调用 AsEnumerable())引擎就越好可以,但有时也有例外。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      • 2012-10-09
      • 1970-01-01
      • 2023-03-07
      • 2020-11-14
      • 2019-06-09
      相关资源
      最近更新 更多