在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中文網其他相關文章!