2013-11-20 29 views
6

我有這樣的LINQ查詢爲什麼實體框架6爲簡單的查找生成複雜的SQL查詢?

dbContext.Customers.Where(c => c.AssetTag == assetTag).Count(); 

(from c in dbContext.Customers 
where c.AssetTag == assetTag 
select c).Count(); 

生成的SQL是

SELECT 
[GroupBy1].[A1] AS [C1] 
FROM (SELECT 
    COUNT(1) AS [A1] 
    FROM [dbo].[Customer] AS [Extent1] 
    WHERE (([Extent1].[AssetTag] = @p__linq__0) AND (NOT ([Extent1].[AssetTag] IS NULL OR @p__linq__0 IS NULL))) OR (([Extent1].[AssetTag] IS NULL) AND (@p__linq__0 IS NULL)) 
) AS [GroupBy1] 

那麼,爲什麼LINQ產生如此複雜的SQL一個簡單的WHERE語句?

+2

您的'[AssetTag]'列允許爲'null'嗎? –

+1

似乎並不複雜,它只是創建一個聲明,以保護您的呼叫從零範圍 – Claies

+0

你能告訴我你如何可以從Linq或Lamda得到這個SQL查詢..這是與你的問題完全無關,我遇到問題。 –

回答

7

in C#string equivalency,null == null evaluates to True。數據庫中的null == null評估爲False。該腳本正在驗證列值和參數都爲空,或者兩者都不爲空,並且它們具有相同的字符串值。

WHERE 
    (
     -- neither the column nor the paramter are null and 
     -- the column and the parameter have the same string value 
     ([Extent1].[AssetTag] = @p__linq__0) AND 
     (NOT ([Extent1].[AssetTag] IS NULL OR @p__linq__0 IS NULL)) 
    ) 
    OR 
    (
     -- both the column value and the parameter are null 
     ([Extent1].[AssetTag] IS NULL) AND 
     (@p__linq__0 IS NULL) 
    ) 
+0

感謝大家的解釋 –

6

WHERE條件產生這種方式,因爲與ANSI NULLS設置,比較AssetTag == null(比較空爲空的結果爲空時,在SQL世界因爲)將不會返回SQL中的相應行。爲了保持查詢行爲與C#開發人員期望的相同,EF生成擴展的WHERE子句。請注意,以前版本的EF沒有這樣做,因此不適用於使用ANSI NULLS設置的數據庫。

GroupBy投影在那裏,因爲EF在.Count()調用之前支持更復雜的查詢,比如連接,投影等。因此,這種方法更通用,因爲它也可以工作所有這些場景。

+0

我正要試着解釋這個程度,但不知道如何解釋它,儘管有一個膚淺的理解。 +1這麼優雅。 – AaronLS

+0

+1提到EF在6之前*不*做這個。 – CrazyPyro

5

首先,在C#c.AssetTag == assetTag將是true,如果兩者都爲null。然而,在SQL中,與任何東西相比總是假的。因此,如果我們想要生成如下C#比較力學查詢,我們必須添加附加條件,以確保空進行比較評估爲true,如果都爲null:

([Extent1].[AssetTag] IS NULL) AND (@p__linq__0 IS NULL)

8

在EF6數據庫空語義默認的比較語義。請注意,這是對EF5中默認設置的更改。在EF5中,此標誌被掩埋在ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior中,默認情況下EF會使用Linq to Object比較語義。在EF6中,它在DbContext上暴露爲DbContext.Configuration.UseDatabaseNullSemantics。您可以找到更多詳細信息here

+2

您鏈接的msdn幫助頁面說'DbContextConfiguration.UseDatabaseNullSemantics'的默認值爲false - 因此在EF6數據庫中,null語義不是默認的比較語義? – springy76