首頁 > 後端開發 > C++ > 如何結合LINQ中類型的邏輯表達式?

如何結合LINQ中類型的邏輯表達式?

DDD
發布: 2025-01-31 06:01:09
原創
585 人瀏覽過

How to Combine Logical Expressions of Type `Expression` in LINQ?

在LINQ中組合Expression<Func<bool>>類型的邏輯表達式

LINQ經常使用表達式,表達式是lambda表達式的表示形式。在處理表達式時,經常需要組合兩個邏輯表達式,例如AND、OR或NOT。

例如,考慮以下兩個表達式:

Expression<Func<bool>> expr1;
Expression<Func<bool>> expr2;
登入後複製

我們可能希望組合這些表達式以獲得相同類型的新的表達式:

// 示例用法(原样无效)
Expression<Func<bool>> andExpression = expr1 AND expr2;
登入後複製

組合具有相同參數的表達式

如果expr1expr2都使用相同的參數,則操作很簡單:

var body = Expression.AndAlso(expr1.Body, expr2.Body);
var lambda = Expression.Lambda<Func<bool>>(body, expr1.Parameters[0]);
登入後複製

組合具有不同參數的表達式

但是,如果表達式使用不同的參數,我們必須注意如何組合它們。使用Invoke可以實現這一點:

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;
}
登入後複製

通用方法

以下代碼片段提供了一種通用方法,用於確定組合表達式的最合適方法:

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);
}
登入後複製

其他注意事項

在.NET 4.0及更高版本中,可以使用ExpressionVisitor類創建EF安全的表達式:

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);
}
登入後複製

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

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板