2010-08-12 63 views
3

我正在使用.NET 4和實體框架來構造一個簡單的查詢。下面是C#代碼:爲什麼LINQ to Entities爲我做一個子查詢?

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爲我做這件事,並且有什麼我可以做的不採取我認爲是從這樣的查詢性能打擊?

+1

爲什麼你認爲這是一個性能問題而不是性能提升(即你測量它/查看查詢計劃)? – nos 2010-08-12 23:30:03

+0

如果沒有'.Take(5)',你會得到什麼? – 2010-08-12 23:43:23

+0

@nos:我的部分是純粹的假設。我想我更加好奇結果的嚴謹表現的不直觀性。 – ladenedge 2010-08-13 00:56:25

回答

3

首先,我懷疑這值得擔心。我在猜測,如果您將EF生成的查詢執行計劃與「最佳」手寫查詢的查詢執行計劃進行比較,則結果將實際上相同。我猜想唯一可能的損失是EF生成的查詢使解析時間延長了幾分之一秒。在事物的宏偉計劃中,這可能不值得考慮。至於爲什麼EF首先以這種方式生成查詢,我很確定它與將LINQ方法轉換爲有效SQL查詢的內在複雜性有關。我敢肯定,執行此翻譯的引擎是非常模塊化的,而且每個模塊都必須生成一部分查詢,這些查詢可以輕鬆地合併到最終的完整查詢中。儘管可以運行最終的「優化」來消除冗餘,但將該任務委派給SQL Server本身的可能性很小。

+0

夠公平的,我可以忍受。謝謝你的想法! – ladenedge 2010-08-13 16:17:07