代码之家  ›  专栏  ›  技术社区  ›  ladenedge

为什么linqto实体要为我做一个子查询?

  •  3
  • ladenedge  · 技术社区  · 15 年前

    我使用.NET4和实体框架来构造一个简单的查询。以下是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
    

    文件哈希 定义为 NVARCHAR(255) .

    这对我来说似乎很奇怪,因为我认为不需要子查询。为什么EF要为我这样做,我能做些什么来避免我认为这样的查询会对性能造成影响?

    1 回复  |  直到 15 年前
        1
  •  3
  •   Daniel Pratt    15 年前

    首先,我怀疑这是否值得担心。我猜,如果您将EF生成的查询执行计划与“最佳”手写查询的执行计划进行比较,结果将完全相同。我猜唯一可能的惩罚是EF生成的查询make要花上几分之一秒的时间来解析。总的来说,这可能不值得考虑。

    至于为什么EF首先以这种方式生成查询,我很确定这与将LINQ方法转换为有效SQL查询的内在复杂性有关。我敢肯定,执行这种转换的引擎是非常模块化的,每个模块必须生成查询的一部分,该部分可以很容易地合并到最终的完整查询中。尽管运行最后的“优化”过程来消除冗余肯定是可能的,但将该任务委托给SQLServer本身可能没有什么坏处。