【问题标题】:SQL equivalent of Count extension method for LINQ isn't obviousLINQ 的 Count 扩展方法的 SQL 等效项并不明显
【发布时间】:2016-08-19 06:21:02
【问题描述】:

我正在使用以下代码对实体框架 (EF) 进行 LINQ 以获取表中的记录数:

 using (var db = new StackOverflowEntities())
 {
      var empLevelCount = db.employeeLevels.Count();
 }

我使用 SQL Server Profiler 捕获了 EF 向数据库发起的查询。我收到以下查询:

SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT(1) AS [A1]
        FROM [dbo].[employeeLevels] AS [Extent1]
    )  AS [GroupBy1]

除了COUNT SQL 函数在 EF 创建的 SQL 查询中被 COUNT_BIG 替换之外,即使对于 LongCount 扩展方法,此查询也完全相同。 LINQ to EF 提供程序创建的查询对我来说看起来很奇怪。为什么不简单地执行如下操作来返回标量计数值?

SELECT 
        COUNT(1) AS [A1]
        FROM [dbo].[employeeLevels] AS [Extent1]

如果有人可以帮助我了解 EF 内部负责的额外后勤工作,这将非常有帮助,这就是 LINQ to EF 提供商创建这样一个查询的原因?似乎 EF 正在尝试通过一些通用算法来处理一些额外的用例,这些算法会产生某种通用查询,就像上面创建的那样。

【问题讨论】:

  • 为什么不简单地在 *db.employeeLevels' 上使用 count()
  • 同意!这确实是一个短手。我已经编辑了我的代码,以将注意力集中在我的真正问题上。我关心的是正在创建的 SQL 查询。
  • 一切都与实施有关。翻译表达式树不是一项简单的任务,需要处理很多情况。只要转换后的 SQL 产生所需的结果,您就不必担心。当然,随着时间的推移,所有这些都可以(并且正在)得到改善。例如,EF Core 生成的 SQL 如下所示:SELECT COUNT(*) FROM [employeeLevels] AS [t] :)

标签: c# sql-server entity-framework linq


【解决方案1】:

在我的数据库中测试这两个查询(适当地更改表)表明它们都生成完全相同的查询计划。所以,结构不应该过多地关注你。在 SQL 中,你告诉系统你想要什么,它会找出最好的方法,在这里优化器能够在给定任一样本的情况下生成最优计划。

至于为什么 LINQ 会生成这样的代码,我怀疑这只是其代码生成器中的一种通用模式,它允许它为任何聚合和后续转换生成类似的代码,而不仅仅是针对未过滤的计数。

【讨论】:

    猜你喜欢
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    相关资源
    最近更新 更多