我试图以编程方式构建一个表达式树。
我的输入中,有一个条件类的列表,其形式如下:
public class Filter
{
public string field { get; set; }
public string operator { get; set; }
public string value { get; set; }
}
在构建Expression
对象时,我按照以下方式为每个条件创建一个Expression
foreach ( Filter sf in rules ) {
Expression ex = sf.ToExpression( query );
if ( mainExpression == null ) {
mainExpression = ex;
}
else {
if ( logicalCondition == "AND" ) {
mainExpression = Expression.And( mainExpression, ex );
}
else if ( logicalCondition == "OR" ) {
mainExpression = Expression.Or( mainExpression, ex );
}
}
}
Filter.ToExpression() 方法的实现方式如下:
public override Expression ToExpression( IQueryable query ) {
ParameterExpression parameter = Expression.Parameter( query.ElementType, "p" );
MemberExpression memberAccess = null;
foreach ( var property in field.Split( '.' ) )
memberAccess = MemberExpression.Property( memberAccess ?? ( parameter as Expression ), property );
ConstantExpression filter = Expression.Constant( Convert.ChangeType( value, memberAccess.Type ) );
WhereOperation condition = (WhereOperation)StringEnum.Parse( typeof( WhereOperation ), operator );
LambdaExpression lambda = BuildLambdaExpression( memberAccess, filter, parameter, condition, value );
return lambda;
}
当我只有一个条件时,一切正常,但是当我尝试使用And
、Or
、AndAlso
或OrElse
静态方法结合表达式时,我会收到一个InvalidOperationException
异常,其内容为:
二元运算符“Or”未为类型“System.Func
2[MyObject,System.Boolean]'和'System.Func
2[MyObject,System.Boolean]'定义。
我有点困惑。有人能更好地解释一下这个异常的原因并提出解决方案吗?
非常感谢!
ExpressionVisitor
来自LinqKit源代码,并且已经能够看到它的工作原理。现在的问题是:IEnumerable<ParameterExpression>
的Zip
方法来自哪里?我正在使用.NET 3.5,但找不到该方法:( - LorenzoExpressionVisitor
类和Enumerable.Zip
扩展方法的.NET 4。我会尝试着让3.5也能工作,但那会更加复杂。 - user743382Enumerable.Zip
并不是必需的,所以我将其删除,并添加了一个简单的for
循环来代替它。 - user743382