2013-03-30 60 views
1

我今天在我的一個Linq-To-Entitites查詢中偶然發現了一個null ref異常,並想知道這怎麼可能。似乎有條件的OR用作OR-gate在Linq-To-Entities中沒有效果。我查詢的一個簡單的例子是這樣的:條件OR對Linq-to-entities沒有影響嗎?

from a in db.Articles 
where a.Author == "John Doe" 
&& (tag == null || a.Tags.Any(t => t.TagName == tag.TagName)) 
select a; 

現在,當標籤是NULL,對那裏查詢仍然會被執行並且在tag.TagName出現一個空引用異常的右側。也許這是因爲Linq-To-Entities總是將完整的語句翻譯成SQL?

無論如何...如何解決這個問題?

非常感謝:)

回答

3
var query = db.Articles.Where(x => x.Author == "John Doe"); 
query = tag == null 
    ? query 
    : query.Where(x => x.TagName == tag.TagName); 

或:

var query = from a in db.Articles 
      where a.Author == "John Doe" 
      select a; 

    query = tag == null 
     ? query 
     : from a in query 
      where a.Tags.Any(t => t.TagName == tag.TagName) 
      select a; 

就個人而言,我覺得第一個清潔

+0

非常感謝,馬特!我很好奇,現在生成的SQL看起來像什麼......將嘗試它:) –

1

想想SQL。 Linq將你的代碼作爲一個整體轉換成sql查詢,將'outside'對象作爲參數傳遞並進行評估。這就是爲什麼它不能評估你的null對象。

它是構建基於條件,以減少在導致查詢不必要的代碼數量由位LINQ查詢位一個很好的做法,所以最好分裂查詢:

var query = db.Articles.Where(x => x.Author == "John Doe"); 
if(tag != null) 
    query = query.Where(x => x.TagName == tag.TagName); 

由於您的查詢進行評估並在選擇時執行,歡迎您添加更多條件而不必擔心多個請求。

+0

感謝Dima,也用於確認Linq-To-Entities將整個查詢直接轉換爲SQL並不應用任何C#邏輯的行爲。 –