提问人:BeanFlicker 提问时间:9/25/2023 最后编辑:Ken WhiteBeanFlicker 更新时间:9/27/2023 访问量:42
如何组合动态类型的表达式
How to Combine Expressions of dynamic Types
问:
我想看看我是否可以 AndAlso 两个类型的 dynamic 表达式。与我实际正在做的事情相比,这个示例非常简单,但它传达了这一点。我见过的所有使用 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,它不包含所需的绑定
答:
-1赞
NetMage
9/27/2023
#1
鉴于
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);
此代码假定存在一个标准扩展,该扩展将任何出现的扩展替换为另一个。
您可以轻松编写自己的课程,也可以使用EF Core课程来创建一个。ExpressionVisitor
Expression
Replace()
ReplacingExpressionVisitor
评论
e1
dynamic
object
e2
AndAlso
dynamic
e1
e2
&&
(new { MyName = "a" }) && (new { MyValue = "b" })
dynamic