替换表达式正文中的参数名称

我正在尝试基于Specification对象动态构建表达式。

我创建了一个ExpressionHelper类,它有一个私有的表达式,如下所示:

private Expression<Func> expression; public ExpressionHelper() { expression = (Expression<Func>)(a => true); } 

然后一些简单的方法如下:

 public void And(Expression<Func> exp); 

我正在和And方法的身体挣扎。 我基本上想要从exp删除主体,将所有参数替换为expression的参数,然后将其附加到expression主体的末尾和AndAlso。

我做到了这个:

 var newBody = Expression.And(expression.Body,exp.Body); expression = expression.Update(newBody, expression.Parameters); 

但最终我的表达看起来像这样:

 { a => e.IsActive && e.IsManaged } 

有更简单的方法吗? 或者我怎样才能撕掉那些e并用一个替换它们?

这里最简单的方法是Expression.Invoke ,例如:

 public static Expression> AndAlso( Expression> x, Expression> y) { return Expression.Lambda>( Expression.AndAlso(x.Body, Expression.Invoke(y, x.Parameters)), x.Parameters); } 

这适用于LINQ-to-Objects和LINQ-to-SQL,但EF不支持。 对于EF,你可能需要使用访问者重写树,遗憾的是。

使用以下代码: 在c#中组合两个lambda表达式

 public static Expression> AndAlso( Expression> x, Expression> y) { var newY = new ExpressionRewriter().Subst(y.Parameters[0], x.Parameters[0]).Inline().Apply(y.Body); return Expression.Lambda>( Expression.AndAlso(x.Body, newY), x.Parameters); } 

或者在.NET 4.0中,使用ExpressionVisitor

 class ParameterVisitor : ExpressionVisitor { private readonly ReadOnlyCollection from, to; public ParameterVisitor( ReadOnlyCollection from, ReadOnlyCollection to) { if(from == null) throw new ArgumentNullException("from"); if(to == null) throw new ArgumentNullException("to"); if(from.Count != to.Count) throw new InvalidOperationException( "Parameter lengths must match"); this.from = from; this.to = to; } protected override Expression VisitParameter(ParameterExpression node) { for (int i = 0; i < from.Count; i++) { if (node == from[i]) return to[i]; } return node; } } public static Expression> AndAlso( Expression> x, Expression> y) { var newY = new ParameterVisitor(y.Parameters, x.Parameters) .VisitAndConvert(y.Body, "AndAlso"); return Expression.Lambda>( Expression.AndAlso(x.Body, newY), x.Parameters); }