我正在使用 .NET 4 和 Entity Framework 构建一个简单的查询。这是 C# 代码:
return Context.Files.Where(f => f.FileHash != 40)
.OrderByDescending(f => f.Created)
.Take(5);
当我使用 ObjectQuery.ToTraceString()
跟踪查询时,我发现了以下子查询:
SELECT TOP (5)
[Project1].[ID] AS [ID],
-- <snip> lots of columns
[Project1].[FileHash] AS [FileHash]
FROM ( SELECT
[Extent1].[ID] AS [ID],
-- <snip> lots of columns
[Extent1].[FileHash] AS [FileHash]
FROM [dbo].[Files] AS [Extent1]
WHERE (LEN([Extent1].[FileHash])) <> 40
) AS [Project1]
ORDER BY [Project1].[Created] DESC
FileHash 被定义为 NVARCHAR(255)。
这对我来说似乎很奇怪,因为我认为不需要子查询。为什么 EF 为我做这件事,我可以做些什么来避免我认为此类查询对性能造成影响?
最佳答案
首先,我怀疑这是否值得担心。我猜想如果将 EF 生成的查询执行计划与“最佳”手写查询的查询执行计划进行比较,结果实际上是相同的。我猜唯一可能的惩罚是 EF 生成的查询使解析时间延长了几分之一秒。从大局来看,这可能不值得考虑。
至于为什么 EF 首先以这种方式生成查询,我很确定这与将 LINQ 方法转换为有效 SQL 查询的固有复杂性有关。执行此翻译的引擎是非常模块化的,我敢肯定,每个模块都必须生成可以轻松合并到最终完整查询中的查询的一部分。尽管运行最终“优化”过程以消除冗余当然是可能的,但将该任务委托(delegate)给 SQL Server 本身可能没有什么坏处。
关于sql - 为什么 LINQ to Entities 为我创建子查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3472773/