表达式:用另一个类的属性替换参数

问题描述 投票:0回答:1

我有两个班级:

  • A
  • B

B
有一个属性指向另一个
B.A
.

A
中,我有一个方法
IsEqual
返回一个将被EntityFramework使用的表达式。

我想在

B
中有一个方法,它从
A.IsEqual
获取表达式主体并用作参数
B.A
而不是仅
A
.

所以需要

m => m.Id == other.Id

并将其转换为

m => m.A.Id == other.A.Id

这可能吗?

c# lambda entity-framework-core expression
1个回答
0
投票

是的,使用 C# 可以实现您想要做的事情。您可以在 B 类中创建一个方法,该方法将 lambda 表达式作为参数,然后使用 ExpressionVisitor 修改表达式以使用属性 B.A 而不是 A.

这是 B 中方法的示例实现:

public Expression<Func<B, bool>> GetEqualExpression(Expression<Func<A, bool>> expression)
{
    // Use an expression visitor to replace references to A with B.A
    var visitor = new ReplaceParameterVisitor(expression.Parameters[0], Expression.Property(Expression.Parameter(typeof(B), "m"), "A"));
    var modifiedExpression = visitor.Visit(expression.Body);

    // Combine the modified expression with a lambda expression that takes a B parameter
    return Expression.Lambda<Func<B, bool>>(modifiedExpression, Expression.Parameter(typeof(B), "m"));
}

此方法接受一个返回 bool 且具有 A 类型参数的表达式,并返回使用 B.A 而不是 A 且具有 B 类型参数的修改表达式。它通过使用 ExpressionVisitor 遍历表达式树来实现并将对 A 参数的引用替换为对 B.A.

的引用

这里是 ReplaceParameterVisitor 类的实现:

private class ReplaceParameterVisitor : ExpressionVisitor
{
    private readonly ParameterExpression _oldParameter;
    private readonly Expression _newExpression;

    public ReplaceParameterVisitor(ParameterExpression oldParameter, Expression newExpression)
    {
        _oldParameter = oldParameter;
        _newExpression = newExpression;
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        if (node == _oldParameter)
        {
            return _newExpression;
        }

        return base.VisitParameter(node);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.