结合两个表达式(表达式>)

结合两个表达式(表达式>),第1张

结合两个表达式(表达式>)

好了,您可以使用

expression.AndAlso
/
OrElse
etc组合逻辑表达式,但是问题是参数;您
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);        }    }


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5588160.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存