c# - 从现有表达式在父对象上创建表达式树,用于 c# mongodb 驱动程序解析

标签 c# expression expression-trees mongodb-.net-driver expressionvisitor

我有这样一个类:

public class Person
{
    public string Name { get; set; }

    public string Email { get; set; }

    // ...
}

我还有一个通用类,例如:

public class MyParentObject<T>
{

    public T Item { get; set; }

    // ...
}

例如,我有一个这样的表达式:

Expression<Func<Person, bool>> expression = p => p.Name == "MyName" && p.Email = "example@test.com"

如何将这个表达式转换为:

Expression<Func<MyParentObject<Person>, bool>> expression = p => p.Item.Name == "MyName" && p.Item.Email = "example@test.com"

编辑:

我觉得我的问题还不够深入,我想要这样的方法:

public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression(Expression<Func<T, bool>> expression)
{
    Expression <Func<MyParentObject<T>, bool>> result = // process...
    // ...
    return result;
}

编辑:

我必须创建一个新的树表达式,然后由 c# mongodb 驱动程序解析。我不能在表达式树上使用调用其他编译方法。

我想我必须使用 ExpressionVisitor但我不知道怎么...

最佳答案

您可以使用 Expression.Invoke对于这样的

public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression<T>(Expression<Func<T, bool>> expression)
{
    Expression<Func<MyParentObject<T>, T>> item = parent => parent.Item;
    var result = Expression.Lambda<Func<MyParentObject<T>, bool>>(
        Expression.Invoke(expression, item.Body), item.Parameters);
    return result;
}

更新:另一种需要更多代码但消除了Expression.Invoke 的方法是使用ExpressionVisitor。派生类像这样替换传递的表达式的参数

public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression<T>(Expression<Func<T, bool>> expression)
{
    Expression<Func<MyParentObject<T>, T>> item = parent => parent.Item;
    var body = new ParameterExpressionReplacer { source = expression.Parameters[0], target = item.Body }.Visit(expression.Body);
    var result = Expression.Lambda<Func<MyParentObject<T>, bool>>(body, item.Parameters);
    return result;
}

class ParameterExpressionReplacer : ExpressionVisitor
{
    public ParameterExpression source;
    public Expression target;
    protected override Expression VisitParameter(ParameterExpression node)
    {
        return node == source ? target : base.VisitParameter(node);
    }
}

关于c# - 从现有表达式在父对象上创建表达式树,用于 c# mongodb 驱动程序解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34613924/

相关文章:

yii2 - 使用表达式 Yii2 选择字符串被检测为列

c# - expression.bind 和 expression.assign 之间有什么区别(或 : what is special about MemberBinding)

c# - 如何告诉 GridView 在 CellClick 上打开超链接?

c# - 连接调试器时的 Azure 远程调试对象引用

javascript - 在嵌入式 JavaScript 中插入 AssemblyInfo(例如 DLL 版本号)

linq - .NET 3.5 表达式树中的赋值

c# - Expression.Convert 不会为不变值类型参数抛出 InvalidOperationException?

c# - 使用 CaSTLe Windsor 注入(inject)日志依赖

C:找到算术表达式类型的最大值和最小值

python - Polars - 如何用 Polars 表达式替换 df 中特定行和列的值(例如 df[3,4]=12)?