如何组合动态类型的表达式

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

我想看看是否可以 AndAlso 两个动态类型的表达式。与我实际所做的相比,这个示例非常简单,但它说明了要点。我见过的使用 PedicateBuilder 或 ExpressionBuilder 的所有示例都要求表达式为 bool 类型,并且通常用作“Where”子句。这个返回一个新的动态对象。

public class MyObject
{
    public string Name { get; set; }
    public string Value { get; set; }   
    public string Comment { get; set; } 
}

Expression<Func<MyObject, dynamic>> e1 = i => new { MyName = i.Name };
Expression<Func<MyObject, dynamic>> e2 = i => new { MyValue = i.Value };

我希望得到 e1 && e2 的组合表达式。我以正确的方式处理这件事吗?

更新1: 我已经尝试过这个答案,但它需要输入为 MemberInitExpression,并且我有 NewExpression,它不包含所需的绑定

c# linq-expressions c#-10.0
1个回答
0
投票

给定

Expression<Func<MyObject, dynamic>> e1 = i1 => new { MyName = i1.Name };
Expression<Func<MyObject, dynamic>> e2 = i2 => new { MyValue = i2.Value };

您可以创建一个具有这两个属性的新匿名类型。我将手动创建它:

var mo = new MyObject();
mo.Name = "a";
mo.Value = "1";
var make_e1_2 = new { MyName = mo.Name, MyValue = mo.Value };

然后您可以从

e1
e2
中提取参数和主体,并使用它们来调用新类型构造函数:

// (MyObject i1)
var e1_2Parm = e1.Parameters[0];

// new { MyName = i1.Name }
var e1Body = (NewExpression)e1.Body;
// new { MyValue = i1.Value }
var e2Body = (NewExpression)e2.Body.Replace(e2.Parameters[0], e1_2Parm);

// .ctor(string MyName, string MyValue)
var e1_2Constructor = make_e1_2.GetType().GetConstructors().First();

// new { MyName = i1.Name, MyValue = i1.Value }
var e1_2Body = Expression.New(e1_2Constructor, e1Body.Arguments[0], e2Body.Arguments[0]);

// (MyObject i1) => new { MyName = i1.Name, MyValue = i1.Value }
var e1_2 = Expression.Lambda<Func<MyObject, dynamic>>(e1_2Body, e1_2Parm);

此代码假设存在标准

ExpressionVisitor
扩展,它将任何出现的一个
Expression
替换为另一个
Replace()
。 您可以轻松编写自己的类,也可以使用 EF Core
ReplacingExpressionVisitor
类来创建一个。

© www.soinside.com 2019 - 2024. All rights reserved.