[英]Lambda expression weirdness in a LINQ to SQL 'where' condition
我正在開發一個ASP.NET MVC應用程序,它使用帶有LINQ to SQL的存儲庫模式作為我的數據源。 在我的存儲庫中,我公開了以下方法:
public IEnumerable<T> Find(Expression<Func<T, bool>> where)
{
return _context.GetTable<T>().Where(where);
}
我可以這樣說:
repository<User>().Find(u => true);
但是,如果我嘗試做(當搜索為空時)
repository<User>().Find(u => !string.IsNullOrEmpty(search) ? u.UserName.Contains(search) : true);
我收到錯誤:
值不能為空。 參數名稱:文本
我認為lambda表達式將執行相同的操作,因為search的值為null,但顯然不是這種情況。
我該如何解決這個問題?
因為這是一個表達式,所以不會自動應用正常的條件運算符邏輯(不評估false表達式)。 由於表達式實際上被轉換為SQL查詢表達式,LINQ to SQL正在評估條件的參數,在這種情況下它是null
。 雖然LIKE null
是有效的SQL語法,但顯然LINQ to SQL不贊賞傳遞null。 您將不得不構造兩個不同的查詢,一個用於空術語,一個用於非空術語。
要么是這樣,要么將string.Empty
傳遞給Contains
。 這里唯一的影響是無法在列上使用索引,因為服務器將對每一行進行重復的條件評估,從而強制進行表掃描。 我建議在沒有條件的情況下使用兩個查詢。
包含一個字符串。 你應該傳遞string.Emtpy
。
u.UserName.Contains(search)
如果你試試這個,它會編譯,但你會得到一個運行時錯誤:
string str = "Leniel";
if (str.Contains(null))
{
var num = 1;
}
錯誤:
Value cannot be null.
Parameter name: value
要添加其他答案,如果你必須遵循這個理想,你可以簡單地這樣做:
repository<User>.Find(u => string.IsNullOrEmpty(search) ||
u.UserName.Contains(search));
在盲目實施之前,如果你這樣做,請閱讀亞當的答案以了解后果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.