在LINQ中组合Expression<Func<bool>>
类型的逻辑表达式
LINQ经常使用表达式,表达式是lambda表达式的表示形式。在处理表达式时,经常需要组合两个逻辑表达式,例如AND、OR或NOT。
例如,考虑以下两个表达式:
<code class="language-csharp">Expression<Func<bool>> expr1; Expression<Func<bool>> expr2;</code>
我们可能希望组合这些表达式以获得相同类型的新的表达式:
<code class="language-csharp">// 示例用法(原样无效) Expression<Func<bool>> andExpression = expr1 AND expr2;</code>
组合具有相同参数的表达式
如果expr1
和expr2
都使用相同的参数,则操作很简单:
<code class="language-csharp">var body = Expression.AndAlso(expr1.Body, expr2.Body); var lambda = Expression.Lambda<Func<bool>>(body, expr1.Parameters[0]);</code>
组合具有不同参数的表达式
但是,如果表达式使用不同的参数,我们必须注意如何组合它们。使用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>
通用方法
以下代码片段提供了一种通用方法,用于确定组合表达式的最合适方法:
<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>
其他注意事项
在.NET 4.0及更高版本中,可以使用ExpressionVisitor
类创建EF安全的表达式:
<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); }</code>
This revised output maintains the original image and provides a more concise and readable explanation of the code snippets. The code examples are also formatted for better readability.
以上是如何结合LINQ中类型的逻辑表达式?的详细内容。更多信息请关注PHP中文网其他相关文章!