Func
s、 因为您使用的是实体框架,这将导致整个数据集被下载到内存中,搜索在本地完成。你应该用的是
Expression<Func<T, bool>>
相反。
幸运的是
Marc Gravell
有
already written a handy bit of code to combine expressions
. 你的问题严格来说是双重的,因为你想把两个以上的问题组合在一起,但这很容易用一点Linq。所以,让我们先从表达式开始,代码几乎没有变化:
var expressions = new List<Expression<Func<User, bool>>>()
{
(u) => u.Id.Equals(entityToFind.Id),
(u) => u.UserName == entityToFind.UserName,
(u) => u.Email == entityToFind.Email
};
现在使用Marc的代码
or
and
:
public static class ExpressionExtensions
{
public static Expression<Func<T, bool>> OrElse<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var parameter = Expression.Parameter(typeof(T));
var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
var left = leftVisitor.Visit(expr1.Body);
var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
var right = rightVisitor.Visit(expr2.Body);
return Expression.Lambda<Func<T, bool>>(
Expression.OrElse(left, right), parameter);
}
private class ReplaceExpressionVisitor
: ExpressionVisitor
{
private readonly Expression _oldValue;
private readonly Expression _newValue;
public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
{
_oldValue = oldValue;
_newValue = newValue;
}
public override Expression Visit(Expression node)
{
if (node == _oldValue)
return _newValue;
return base.Visit(node);
}
}
}
不,你把你的表情和Linq结合起来
Aggregate
方法:
var combinedExpression = expressions.Aggregate((x, y) => x.OrElse(y));
然后像这样使用它:
var result = db.Things.Where(combinedExpression);