如果您使用内存数据(阅读“POCO 集合”),您还可以使用 PredicateBuilder 将表达式堆叠在一起,如下所示:
// initial "false" condition just to start "OR" clause with
var predicate = PredicateBuilder.False<YourDataClass>();
if (condition1)
{
predicate = predicate.Or(d => d.SomeStringProperty == "Tom");
}
if (condition2)
{
predicate = predicate.Or(d => d.SomeStringProperty == "Alex");
}
if (condition3)
{
predicate = predicate.And(d => d.SomeIntProperty >= 4);
}
return originalCollection.Where<YourDataClass>(predicate.Compile());
提到的PredicateBuilder 的完整来源如下(但您也可以通过更多示例查看original page):
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T> () { return f => true; }
public static Expression<Func<T, bool>> False<T> () { return f => false; }
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
}
}
注意:我已经用Portable Class Library 项目测试了这种方法,并且必须使用.Compile() 才能使其工作:
Where(谓词 .Compile() );