【问题标题】:LINQ generating sub query for a simple order byLINQ为一个简单的订单生成子查询
【发布时间】:2013-10-06 17:01:45
【问题描述】:

我无法理解为什么 SQL 输出中包含我在 LINQ 中编写的简单查询的子查询。这是我的代码:

var list = db.User.Where(u => u.Name == somename).OrderBy(u => u.IdUser).ToList();

其中 somename 是我在执行时传递的参数。

输出的SQL是:

SELECT
Project1.IdUser, 
Project1.Name
FROM (SELECT
Extent1.IdUser, 
Extent1.Name
FROM user AS Extent1
WHERE Extent1.Name = 'John' /* @p__linq__0 */) AS Project1
ORDER BY 
Project1.IdUser ASC

输出真的应该有一个简单的子查询吗?

我也试过

var list = db.User.Where(u => u.Name.Equals(somename)).OrderBy(u => u.IdUser).ToList();

生成与上面相同的输出。

如果我对参数进行硬编码,例如:

var list = db.User.Where(u => u.Name == "John").OrderBy(u => u.IdUser).ToList();

它按预期工作,只生成

SELECT
Extent1.IdUser, 
Extent1.Name
FROM user AS Extent1
WHERE 'John' /* @gp1 */ = Extent1.Name
ORDER BY 
Extent1.IdUser ASC

我正在使用的一些东西:

  • EntityFramework 5,.NET 4.5
  • SQL Server 2012
  • Glimpse(使用 MiniProfiler)查看生成的 SQL

我不是 LINQ 专家,所以我在这里缺少什么?

【问题讨论】:

  • 两者的查询计划有区别吗?
  • 不,它们解析为相同的执行计划,但这种语法让我感到困惑。想象一下,如果我正在调试一个由 LINQ 生成的更复杂的查询,并且具有所有不必要的复杂性,那将不会有效率。
  • 抽象是有代价的。如果您不喜欢成本,请自己编写 SQL。这些选择没有对错之分。
  • 那么这样一个简单的查询需要这个子查询吗?你能详细说明它为什么这样做吗?我知道抽象是有代价的,我想弄清楚我是否做错了什么,因为正如我所说,我不是 LINQ 专家。
  • 不,我不知道 Linq 会为任何东西生成什么。如果它足够快,我会使用它。如果速度太慢,我会尝试优化(由于查询膨胀,这可能会很困难),如果不能,我会使用 SQL。

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


【解决方案1】:

正如其他人指出的那样,查询结果与您的执行计划相同。实体框架(和 LINQ to Entites)可帮助您避免编写 SQL 和为 SQL 烦恼(在某种程度上)。在正常情况下,您不关心生成的 SQL 也不关心“调试”它。您只关心 LINQ 查询是否正确。实体框架(应该)将其转换为正确的(有时甚至是预期的)SQL(同样,执行计划很重要)。

我并不是说您不应该出于性能原因查看 SQL(或者更好地说是该查询的执行计划)。但这应该在您发现性能问题之后进行。你应该先尝试编写查询simple,这才是成功之道。当然,如果您了解 SQL,您就会知道集合世界与对象世界不同 - 您可以在 LINQ 中轻松编写相当普通的查询(感谢对象世界),但这最终会成为令人讨厌的 SQL(集合世界),因为“世界之间的不匹配”。

【讨论】:

  • 我认为这仍然是一个有效的问题,但遗憾的是没有得到回答。也许今天你可以通过打开一个问题来获得 EF Core 团队的意见。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-06
  • 1970-01-01
相关资源
最近更新 更多