我很難找出最好的方法來做到這一點,我會很感激任何幫助。Linq-to-SQL:組合(OR'ing)多個「Contains」過濾器?
基本上,我設置了一個過濾器,允許用戶查看與用戶名的任意「過濾器」相關的審計項目的歷史。數據源是一個SQL Server數據庫,所以我正在使用IQueryable「source」(從db上下文對象獲得的直接表引用,或者可能是由其他查詢產生的IQueryable引用),應用WHERE過濾器,然後返回結果IQueryable對象....但我有點難以理解如何使用這種方法執行OR。
我考慮過去表達式的路由,因爲我知道如何或者那些,但我一直無法弄清楚如何做到這一點與「包含」類型的評估,所以我目前正在使用一個聯盟,但恐怕這可能會對性能產生負面影響,而且我想知道如果其他過濾器(除了此處顯示的用戶名過濾之外)以arbirary順序添加,它是否可能不會給我所需的東西。
這裏是我的示例代碼:
public override IQueryable<X> ApplyFilter<X>(IQueryable<X> source)
{
// Take allowed values...
List<string> searchStrings = new List<string>();
// <SNIP> (This just populates my list of search strings)
IQueryable<X> oReturn = null;
// Step through each iteration, and perform a 'LIKE %value%' query
string[] searchArray = searchStrings.ToArray();
for (int i = 0; i < searchArray.Length; i++)
{
string value = searchArray[i];
if (i == 0)
// For first step, perform direct WHERE
oReturn = source.Where(x => x.Username.Contains(value));
else
// For additional steps, perform UNION on WHERE
oReturn = oReturn.Union(source.Where(x => x.Username.Contains(value)));
}
return oReturn ?? source;
}
這感覺就像是錯誤的方式做事情,但它似乎工作,所以我的問題是,第一,是否有更好的方法來做到這一點?另外,有沒有辦法用表達式來做'Contains'或'Like'?
(Editted糾正我的代碼:在回滾到以張貼工作狀態,我顯然沒有回滾相當遠遠不夠:))
========== ===================================
ETA:根據給出的解決方案,這裏是我的新代碼(如果任何閱讀有興趣):
public override IQueryable<X> ApplyFilter<X>(IQueryable<X> source)
{
List<string> searchStrings = new List<string>(AllowedValues);
// <SNIP> build collection of search values
string[] searchArray = searchStrings.ToArray();
Expression<Func<X, bool>> expression = PredicateBuilder.False<X>();
for (int i = 0; i < searchArray.Length; i++)
{
string value = searchArray[i];
expression = expression.Or(x => x.Username.Contains(value));
}
return source.Where(expression);
}
(一個警告,我注意到:繼PredicateBuilder的例子,一個空的集合Ø f搜索字符串將返回false(false || value1 || ...),而在我原來的版本中,我假設一個空的清單應該只是過濾未過濾的來源。因爲我認爲它更多的,新版本似乎更有意義,我的需要,所以我採取了)
====================== =======================
順便說一句,LINQ確實有[LIKE](http://msdn.microsoft.com/en-us/library/system.data.linq.sqlclient.sqlmethods.like.aspx)方法(不知道你有意使用包含,但你的評論提到LIKE)。 – 2010-12-21 16:20:15
爲什麼不在填充搜索字符串列表的塊中執行where和union操作?換句話說,而不是`searchStrings.Add(newString),`使用`結果= source.Where(X => x.Username.Contains(newString))`或`結果= result.Union(source.Where(X => x.Username.Contains(newString)))`。 – phoog 2010-12-21 17:09:44