【问题标题】:How to combine two C# Expressions using API? [duplicate]如何使用 API 组合两个 C# 表达式? [复制]
【发布时间】:2021-07-21 21:24:32
【问题描述】:

假设我有两个类,如下所示:

public class A
{
  public B B { get; set; }
}
public class B
{
  public string SomeValue { get; set; } 
}

还有以下表达式:

using System.Linq.Expressions;
// Actual expression much more complicated
Expression<Func<B, string>> mainExpression = b => b.SomeValue; 
Expression<Func<A, B>> aToB = a => a.B;

我将如何组合它们?显然我可以写

Expression<Func<A, string>> newExpression = a => a.B.SomeValue;

但真正的“mainExpression”要复杂得多,我想避免代码重复。

我正在使用 EntityFramework,这些是代表数据库表的类,这就是为什么我需要一个 System.Linq.Expressions.Expression 对象。

【问题讨论】:

    标签: c# entity-framework linq-expressions


    【解决方案1】:

    您可以将mainExpression 的参数替换为aToB 的主体(例如,使用自EF Core 3.0 起可用的ReplacingExpressionVisitor,如果您使用的是早期版本,请编写your own one)并构建一个新的表达式树:

    Expression<Func<B, string>> mainExpression = b => b.SomeValue; 
    Expression<Func<A, B>> aToB = a => a.B;
    var visit = new ReplacingExpressionVisitor(new[] {mainExpression.Parameters[0]}, new[] {aToB.Body})
        .Visit(mainExpression.Body);
    var result = Expression.Lambda<Func<A, string>>(visit, aToB.Parameters);
    

    【讨论】:

    • 这是否适用于 EF 你还知道吗?
    • @Adam 是的,它应该(虽然取决于实际表达式)。你试过了吗?
    • 我想我得自己写了。我正在使用 EF6,但这绝对有帮助。
    • @GuruStron:请问您如何使用此类将参数替换为新定义的ParameterExpression?我使用的是自定义 ExpressionVisitor 类。但我不确定ReplacingExpressionVisitor 构造函数的参数应该是什么。
    • @JonathanWood ReplacingExpressionVisitor ctor 接受两个集合 - 第一个要替换什么,第二个 - 替换,所以它应该类似于 new ReplacingExpressionVisitor(new[] {mainExpression.Parameters[0]}, new[] {filterParam}) 其中filterParam 是新定义的ParameterExpression
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    相关资源
    最近更新 更多