2014-11-03 40 views
2

問題:我想根據我的方法的輸入在我的linq查詢中構造一個動態條件。在linq中使用lambda表達式的正確方法

假設我的方法接受名字,姓氏和郵編。用戶可以選擇在我的方法中傳遞一個或多個。

我的LINQ查詢看起來像:

var query = (from employee in EmployeeDb.Employees 
      select employee) 
//Adding firstname to where. Similarly I add other conditions. 
if (request.FirstName != string.Empty) 
    query = query.Where(c => c.FirstName == request.FirstName); 

當我想到我的SQL查詢的WHERE條件是這樣的:

WHERE [Extent6].[LastName] = @p__linq__1 AND [Extent6].[FirstName] = @p__linq__0 

我實際上看到的是:

WHERE (([Extent6].[LastName] = @p__linq__0) OR (([Extent6].[LastName] IS NULL) AND (@p__linq__0 IS NULL))) AND (([Extent6].[FirstName] = @p__linq__1) OR (([Extent6].[FirstName] IS NULL) AND (@p__linq__1 IS NULL))) 

而那顯然造成了很多性能問題。我究竟做錯了什麼?

+2

你把你的db列設置爲「NOT NULL」嗎? – 2014-11-03 16:51:11

+0

@ErenErsönmez偉大的一點。它們是NULL。我可以將名稱更改爲不爲空,但其他一些參數可以爲NULL。所以如果一個數據庫列可以是NULLable,這意味着Linq會自動添加這些檢查?沒有辦法禁用它? – user3726933 2014-11-03 16:55:02

+2

看起來像EF 6.0+中有一個'DbContextConfiguration.UseDatabaseNullSemantics'屬性。 – 2014-11-03 17:02:04

回答

2

問題的存在是因爲c#和大多數數據庫處理空值的區別。在C#中,null == null爲true,而在大多數數據庫中,null == null將返回false(或未知)。 LINQ正試圖編寫一個與C#的空值思想相匹配的SQL查詢。由於您的字段可以爲空,並且您可以要求所有Firstname爲空的記錄,這是有道理的。如果您不希望Firstname爲空,那麼您應該將其設置爲NOT NULL字段,並且LINQ將爲您生成更簡單的查詢。

或者,您可以將您的上下文對象的UseDatabaseNullSemantics屬性設置爲true,它將簡化您的查詢,但是您將無法請求記錄Firstname爲null的記錄。