好了,您可以使用
expression.AndAlso/
OrElseetc组合逻辑表达式,但是问题是参数;您
Parameterexpression在expr1和expr2中使用相同的代码吗?如果是这样,则更容易:
var body = expression.AndAlso(expr1.Body, expr2.Body);var lambda = expression.Lambda<Func<T,bool>>(body, expr1.Parameters[0]);
这也可以很好地否定单个 *** 作:
static expression<Func<T, bool>> Not<T>( this expression<Func<T, bool>> expr){ return expression.Lambda<Func<T, bool>>( expression.Not(expr.Body), expr.Parameters[0]);}
否则,根据LINQ提供程序,您可能可以将它们与
Invoke:
// OrElse is very similar...static expression<Func<T, bool>> AndAlso<T>( this expression<Func<T, bool>> left, expression<Func<T, bool>> right){ var param = expression.Parameter(typeof(T), "x"); var body = expression.AndAlso( expression.Invoke(left, param), expression.Invoke(right, param) ); var lambda = expression.Lambda<Func<T, bool>>(body, param); return lambda;}
在某个地方,我有一些代码重新编写了一个替换节点的表达式树,以消除对的需要
Invoke,但是它相当长(而且我不记得我把它留在哪里了……)。
选择最简单路线的通用版本:
static expression<Func<T, bool>> AndAlso<T>( this expression<Func<T, bool>> expr1, expression<Func<T, bool>> expr2){ // need to detect whether they use the same // parameter instance; if not, they need fixing Parameterexpression param = expr1.Parameters[0]; if (ReferenceEquals(param, expr2.Parameters[0])) { // simple version return expression.Lambda<Func<T, bool>>( expression.AndAlso(expr1.Body, expr2.Body), param); } // otherwise, keep expr1 "as is" and invoke expr2 return expression.Lambda<Func<T, bool>>( expression.AndAlso( expr1.Body, expression.Invoke(expr2, param)), param);}
从.NET 4.0开始,有一个
expressionVisitor类允许您构建EF安全的表达式。
public static expression<Func<T, bool>> AndAlso<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.AndAlso(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); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)