>本文演示瞭如何使用邏輯和OR,而不是運算符組合兩個類型的C#表達式。 由於參數不匹配,直接使用Expression<Func<bool>>
之類的操作員是不正確的。 提出了幾種方法,每個方法都解決了不同的方案。 expr1 AND expr2
>
方法1:簡單組合(相同的參數)>
兩種表達式都使用相同的參數,則直接在表達式上使用>或Expression.AndAlso
Expression.OrElse
<code class="language-csharp">var body = Expression.AndAlso(expr1.Body, expr2.Body); var lambda = Expression.Lambda<Func<bool>>(body, expr1.Parameters[0]);</code>>
<code class="language-csharp">static Expression<Func<bool>> Not<T>(this Expression<Func<bool>> expr) { return Expression.Lambda<Func<bool>>(Expression.Not(expr.Body), expr.Parameters[0]); }</code>方法2:使用Indoke
Invoke
<code class="language-csharp">static Expression<Func<bool>> AndAlso<T>(this Expression<Func<bool>> left, Expression<Func<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<bool>>(body, param); return lambda; }</code>將是相似的,用
>。
OrElse
AndAlso
方法3:優化組合(處理相同的和不同的參數)OrElse
如果參數相同,此方法智能選擇了更簡單的方法,否則使用
Invoke
方法4:使用ExpressionVisitor(.NET 4.0和更高版本)
<code class="language-csharp">static Expression<Func<bool>> AndAlso<T>(this Expression<Func<bool>> expr1, Expression<Func<bool>> expr2) { ParameterExpression param = expr1.Parameters[0]; if (ReferenceEquals(param, expr2.Parameters[0])) { return Expression.Lambda<Func<bool>>(Expression.AndAlso(expr1.Body, expr2.Body), param); } return Expression.Lambda<Func<bool>>(Expression.AndAlso(expr1.Body, Expression.Invoke(expr2, param)), param); }</code>的EF-SAFE方法
對於實體框架兼容性,提供了一個可靠的解決方案:
ExpressionVisitor
<code class="language-csharp">public static Expression<Func<bool>> AndAlso<T>(this Expression<Func<bool>> expr1, Expression<Func<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<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); } }</code>
以上是我如何使用C#中的操作員和或者不是運算符組合兩個表達式表達式?的詳細內容。更多資訊請關注PHP中文網其他相關文章!