[英]Linq PredicateBuilder with conditional AND, OR and NOT filters
我們有一個使用LINQ to SQL的項目,為此我需要重寫幾個搜索頁面以允許客戶端選擇是否要執行和 / 或搜索。
我雖然使用PredicateBuilder重做LINQ查詢,但我認為這個工作得很好。 我實際上有一個包含我的謂詞的類,例如:
internal static Expression<Func<Job, bool>> Description(string term)
{
return p => p.Description.Contains(term);
}
要執行搜索,我正在執行此操作(為簡潔起見,省略了一些代碼):
public Expression<Func<Job, bool>> ToLinqExpression()
{
var predicates = new List<Expression<Func<Job, bool>>>();
// build up predicates here
if (SearchType == SearchType.And)
{
query = PredicateBuilder.True<Job>();
}
else
{
query = PredicateBuilder.False<Job>();
}
foreach (var predicate in predicates)
{
if (SearchType == SearchType.And)
{
query = query.And(predicate);
}
else
{
query = query.Or(predicate);
}
}
return query;
}
雖然我對此感到滿意,但我有兩個顧慮:
為了解決第2點,我想我可以通過簡單地重寫我的表達式來做到這一點,例如:
internal static Expression<Func<Job, bool>> Description(string term, bool invert)
{
if (invert)
{
return p => !p.Description.Contains(term);
}
else
{
return p => p.Description.Contains(term);
}
}
然而,這感覺有點像一個kludge,這通常意味着那里有一個更好的解決方案。 任何人都可以推薦如何改善這一點? 我知道動態LINQ,但我真的不想失去LINQ的強類型。
如果您正在尋找更少的線路,您可以使用三元運算符替換if / else:
query = SearchType == SearchType.And ? PredicateBuilder.True<Job>() : PredicateBuilder.False<Job>();
foreach (var predicate in predicates)
{
query = SearchType == SearchType.And ? query.And(predicate) : query.Or(predicate);
}
對於'and not' / 'or not'
部分!
操作員應該做的伎倆。
PD:你是否測試了foreach
部分是否正確設置了謂詞?,據我所知,你正在構建將在稍后的時間點執行的表達式,所以你可能只有一個文字參考,只有最后一個設置謂詞在最后的迭代,這就是為什么你必須使用臨時變量來保存每次迭代的值。
編輯:如果你想否定一個程序性的表達式,這是一個棘手的,你可以嘗試類似的東西:
internal static Expression<Func<Job, bool>> Description(string term, bool invert)
{
return NegateExp<Func<Job, bool>>(p => p.Description.Contains(term), invert);
}
而NegateExp方法將類似於:
public static Expression<TDelegate> NegateExp<TDelegate>(Expression<TDelegate> expression, bool inverse)
{
if (inverse)
{
return Expression.Lambda<TDelegate>(Expression.Not(expression.Body), expression.Parameters);
}
return expression;
}
您可以查看此問題以獲取更多示例是否有任何方法可以否定謂詞?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.