2010-07-16 64 views
0

我有一個頁面,您可以在其中搜索人員。他們可以獲取所有人的列表,或者按照某些標準(如姓或名)對其進行過濾。使用可選搜索子句執行LINQ查詢

到目前爲止,我一直在嘗試使用this question中詳述的技術。

所以我的代碼看起來像

string firstname=... 
string lastname=... 

var people=from p in People.All() 
      where (firstname==null || firstname.ToLower()==p.FirstName.ToLower()) && 
       (lastname==null || lastname.ToLower()==p.LastName.ToLower()) 
      select p; 

然而,我建立查詢時,當這兩個名字和姓氏爲null得到一個空引用錯誤。刪除where子句可以消除錯誤。

爲什麼這不起作用? C#是否嘗試評估where子句每個部分的第二部分?它不應該是因爲短路或正確嗎?

+0

只有一個很高的rep用戶(79k)在這裏發佈了答案。那個答案是正確的。你爲什麼要刪除它? – Earlz 2010-07-16 17:56:53

+0

'你'在這種情況下是用戶,誰顯然刪除了自己的答案。 IIRC,它討論了使用string.IsNullOrEmpty(firstname)和string.Equals()。我認爲他刪除了,因爲他的回答沒有解決你的實際問題,即使它的工作 – 2010-07-16 17:59:45

回答

1

使用string.Equals:

from p in People.All() 
where (firstname == null || string.Equals (firstname, p.FirstName, StringComparison.InvariantCultureIgnoreCase)) && 
     (lastname == null || string.Equals (lastname, p.LastName, StringComparison.InvariantCultureIgnoreCase)) 
select p 

這不僅避免了空的問題,但它強制你指定一個字符串比較類型(一件好事)。換句話說,您可以指定在執行不區分大小寫的比較時是否使用特定於本地或不變文化的規則。

+0

你是LINQPad成名的Albahari兄弟之一嗎?只是好奇... – 2010-08-18 16:32:16

0

確保它不是調用ToLower將前空:

(firstname==null || (firstname!= null && firstname.ToLower()==p.FirstName.ToLower())) 
0

時都爲null,因爲聲明的第一部分將評估爲true,不允許評價的短路,這是行不通的。爲什麼不用等值規則來翻轉陳述?

(firstName != null && firstName.ToLower() == p.firstName.ToLower()) 

編輯:我寫了以下,成功地在LINQPad 4中運行它,沒有問題。我假設撥打People.All()只需返回一個帶有全套記錄的IQueryable<People>?也許在這裏發佈你的例外文本,以便我們可以看到是否有什麼你無意中錯過了?

void Main() 
{ 
    string a = null; 
    string b = null; 
    var peeps = new List<Person> { 
     new Person { 
      FirstName = "John", 
      LastName = "Connor" 
     }, 
     new Person { 
      FirstName = "Sarah", 
      LastName = "Connor", 
     }, 
     new Person { 
      FirstName = "Cletus", 
      LastName = "Handy" 
     } 
    }; 

    var somePeeps = from p in peeps 
     where (a == null || a.ToLower() == p.FirstName.ToLower()) 
      && (b == null || b.ToLower() == p.LastName.ToLower()) 
     select p; 

    somePeeps.Dump(); 

} 

public class Person 
{ 
    public string FirstName { get; set;} 
    public string LastName { get; set;} 
} 
+0

,如果第一部分是真實的,那麼它不應該評估第二部分由於短路OR雖然。 – Earlz 2010-07-16 18:07:53

1

你不需要調用ToLower()使用string.compare與IGNORECASE

代替
string.Compare(firstName, p.FirstName, true)