带有变量的评估表达式<Func<>>
Evaluation Expression<Func<>> with variables
我们公司有一个框架,它请求查询作为 Expression(Func(T, bool)),其中 T 是 Buiniess 对象的给定类型。
我需要为此编写一个 Provider 以及评估表达式内容的内容
如果我有这样的查询:
Expression<Func<Person, bool>> expr;
expr = (p) => p.Name == "Smith";
这没问题,然后我可以使用表达式的主体 属性 给出以下结果
Body = {(p.Name == "Smith")}
如果我这样使用变量:
Expression<Func<Person, bool>> expr;
string nameToFind = "Smith";
expr = (p) => p.Name == name;
我得到以下结果:
Body = {(p.Name == value(TestConsole.Program+<>c__DisplayClass0_0).nameToFind)}
在这种情况下,我想要的是在没有变量的第一个示例中,解析表达式中的变量值。
这可能吗?
如果有示例或提示,我将不胜感激
您要做的是替换任何左侧类型为 ConstantExpression
的 MemberExpression
,使用反射获取值。这就是 ExpressionVisitor
的目的。
public class Simplify : ExpressionVisitor{
protected override Expression VisitMember(MemberExpression node){
var expr = Visit(node.Expression);
if (expr is ConstantExpression c){
if (node.Member is PropertyInfo prop)
return Expression.Constant(prop.GetValue(c.Value), prop.PropertyType);
if (node.Member is FieldInfo field)
return Expression.Constant(field.GetValue(c.Value), field.FieldType);
}
return node.Update(expr);
}
}
expr = new Simplify().Visit(expr);
我们公司有一个框架,它请求查询作为 Expression(Func(T, bool)),其中 T 是 Buiniess 对象的给定类型。
我需要为此编写一个 Provider 以及评估表达式内容的内容
如果我有这样的查询:
Expression<Func<Person, bool>> expr;
expr = (p) => p.Name == "Smith";
这没问题,然后我可以使用表达式的主体 属性 给出以下结果
Body = {(p.Name == "Smith")}
如果我这样使用变量:
Expression<Func<Person, bool>> expr;
string nameToFind = "Smith";
expr = (p) => p.Name == name;
我得到以下结果:
Body = {(p.Name == value(TestConsole.Program+<>c__DisplayClass0_0).nameToFind)}
在这种情况下,我想要的是在没有变量的第一个示例中,解析表达式中的变量值。
这可能吗? 如果有示例或提示,我将不胜感激
您要做的是替换任何左侧类型为 ConstantExpression
的 MemberExpression
,使用反射获取值。这就是 ExpressionVisitor
的目的。
public class Simplify : ExpressionVisitor{
protected override Expression VisitMember(MemberExpression node){
var expr = Visit(node.Expression);
if (expr is ConstantExpression c){
if (node.Member is PropertyInfo prop)
return Expression.Constant(prop.GetValue(c.Value), prop.PropertyType);
if (node.Member is FieldInfo field)
return Expression.Constant(field.GetValue(c.Value), field.FieldType);
}
return node.Update(expr);
}
}
expr = new Simplify().Visit(expr);