2016-03-01 69 views
1

有誰知道爲什麼這樣的邏輯:LINQ增加額外的邏輯WHERE子句

var t = _repo.Surveys 
      .Where(s => s.status && 
         (s.regionid == null || s.regionid.Value.Equals(regionid))) 
      .ToList(); 

將構建該WHERE條款?

WHERE ([Extent1].[status] = 1) 
    AND (([Extent1].[regionid] IS NULL) OR 
     (([Extent1].[regionid] = @p__linq__0) AND (NOT ([Extent1].[regionid] IS NULL OR @p__linq__0 IS NULL))) OR 
     (([Extent1].[regionid] IS NULL) AND (@p__linq__0 IS NULL)))' 
,N'@p__linq__0 int',@p__linq__0=0 

我希望它只會比較列是否爲空或者它是否具有我通過的值。

喜歡的東西:

WHERE status = 1 AND (regionid IS NULL OR regionid = 0),例如。

+1

看起來像一個EF自動生成的查詢。它「嘗試」優化 - 嘗試成爲關鍵詞......我假設在這種情況下,它正在查看一個「可空」屬性並進行相應的轉換。 – sgeddes

+2

你真的讀過每一個比較嗎?它正在做你想做的,它只是更詳細的。 – Ellesedil

+0

@Ellesedil感謝您的評論。我知道它確實有效......我只是在想如果有辦法讓它更清潔。 – Catinodeh

回答

3

您可以通過以下操作清理一點點:

var parameters = new List<Type?>() { null, regionid }; 
var t = _repo.Surveys 
      .Where(s => s.status && parameters.Contains(s.regionid)) 
      .ToList(); 

注與regionid的類型更換Type

這將生成SQL類似於:

WHERE (0 = [Extent1].[Status]) 
    AND ((([Extent1].[RegionId] IN (regionIdValue)) AND ([Extent1].[RegionId] IS NOT NULL)) OR 
     ([Extent1].[RegionId] IS NULL)) 

在這一點上唯一額外 SQL是AND ([Extent1].[RegionId] IS NOT NULL)條件爲IN的一部分。

說了這麼多,那你原來的LINQ是生成的SQL非常有意義。所述(NOT ([Extent1].[RegionId] IS NULL OR @p__linq__0 IS NULL))條件排除的實例,其中任一該數據庫值爲NULL或參數值是NULL。

然後(([Extent1].[regionid] IS NULL) AND (@p__linq__0 IS NULL))條件實際上是有效的在那裏了數據庫值和參數都爲null,則返回值。在你的代碼可以在null傳遞給.Equals功能,它應該返回值。

+0

這將拋出一個運行時錯誤'system.Type'必須是非空值類型,以便將其用作通用類型或方法'System.Nullable '中的參數'T',您可能需要或者您只需使用類型,如果這樣你就應該對 –

+0

@ johnny5我把鍵入有更清楚,因爲我不知道他使用的是什麼呀 – drneel

+0

我想通了這一點以後它好像你正在使用類型的佔位符,其如何將一個實例放在那裏讓我感到困惑,甚至會因爲使用初始化列表而編譯 –