SQL中与LINQ的Count扩展方法等价的方法并不明显。

3

我正在使用LINQ到实体框架(EF)来获取我的表中记录的数量,使用以下代码:

 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]

即使是对于LongCount扩展方法,该查询仍然保持完全相同,除了COUNT SQL函数在EF创建的SQL查询中被COUNT_BIG替换。由LINQ到EF提供程序创建的查询看起来非常奇怪。为什么它不像下面简单地执行以返回标量计数值?

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

如果有人能帮我理解EF内部正在处理的其他物流问题,这将非常有帮助,这就是为什么LINQ to EF提供程序会创建这样的查询?看起来EF也在尝试通过一些常见算法处理一些其他用例,从而导致类似上面所创建的通用查询。


1
为什么不直接在db.employeeLevels上使用count()呢? - Rob
同意!这确实是一种简写。我已经编辑了我的代码,以便将重点放在我的真正问题上。我的关注点在于正在创建的SQL查询。 - RBT
1
重点在于实现。翻译表达式树并不是一项简单的任务,需要处理许多情况。只要转换后的SQL产生了期望的结果,您就不必担心。当然,所有这些都可以(而且正在)随着时间的推移得到改进。例如,EF Core生成的SQL如下所示:SELECT COUNT(*) FROM [employeeLevels] AS [t] :) - Ivan Stoev
1个回答

6
在我的一个数据库中测试两个查询(适当更改表格),结果显示它们都生成了完全相同的查询计划。因此,结构不应过分关注。在SQL中,您告诉系统您想要什么,它会找出最佳方法来实现,优化器能够生成给定任何样本的最佳计划。

enter image description here

关于为什么LINQ会生成这样的代码,我猜测这只是它的代码生成器中的一个通用模式,使其能够为任何聚合和后续转换生成类似的代码,而不仅仅是针对未过滤计数的情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接