在數據操作領域,您可能需要使用邏輯運算符(如 AND、OR 或 NOT)組合兩個 Expression
以下代碼片段說明了您可能面臨的挑戰:
<code>Expression<func bool="">> expr1; Expression<func bool="">> expr2; ... // 这不会按预期工作 Expression<func bool="">> andExpression = expr1 AND expr2;</code>
要使用邏輯運算符組合兩個表達式,您可以選擇以下幾種方法:
如果您在 expr1 和 expr2 中使用相同的 ParameterExpression,您可以簡單地組合它們的正文,並使用原始參數創建一個新的 lambda 表達式。
<code>var body = Expression.AndAlso(expr1.Body, expr2.Body); var lambda = Expression.Lambda<func bool="">(body, expr1.Parameters[0]);</code>
此方法也適用於否定單個表達式:
<code>static Expression<func bool=""> Not<T>( this Expression<func bool=""> expr) { return Expression.Lambda<func bool="">( Expression.Not(expr.Body), expr.Parameters[0]); }</code>
如果兩個表達式使用不同的 ParameterExpression 實例,則根據您的 LINQ 提供程序,您可以使用 Invoke 將它們組合:
<code>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>
此方法適用於 AND 和 OR 運算。
此版本會自動檢測兩個表達式是否使用相同的參數,並相應地調整表達式:
<code>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); } // 否则,使用 Invoke 来组合 return Expression.Lambda<func bool="">( Expression.AndAlso( expr1.Body, Expression.Invoke(expr2, param)), param); }</code>
對於 .NET 4.0 及更高版本,您可以使用 ExpressionVisitor 類創建 EF 安全的表達式。此方法允許您在沒有顯式轉換的情況下用新參數替換原始參數:
<code>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>
通過利用這些方法,您可以無縫地組合各種邏輯表達式,並在您的數據上執行複雜的查詢操作。
以上是如何使用邏輯運算符結合兩個表達式表達式?的詳細內容。更多資訊請關注PHP中文網其他相關文章!