所以,我正在试图找出表情树。我正在尝试将动态等于添加到Queryable中,其中T是几个不同表中的一个。我首先检查表格中是否包含我要过滤的字段。
ParameterExpression param = Expression.Parameter(typeof(TSource), "x");
Expression conversionExpression = Expression.Convert(Expression.Property(param, _sourceProperty), typeof(TList));
Expression<Func<TSource, TList>> propertyExpression = Expression.Lambda<Func<TSource, TList>>(conversionExpression, param);
Expression<Func<TList, TList, bool>> methodExpression = (x, y) => x.Equals(y);
ReadOnlyCollection<ParameterExpression> parameters = propertyExpression.Parameters;
InvocationExpression getFieldPropertyExpression = Expression.Invoke(
propertyExpression,
parameters.Cast<Expression>());
MethodCallExpression methodBody = methodExpression.Body as MethodCallExpression;
MethodCallExpression methodCall = Expression.Call(methodBody.Method, Expression.Constant(equalTo), getFieldPropertyExpression);
Expression<Func<TSource, bool>> equalsStatement = Expression.Lambda<Func<TSource, bool>>(methodCall, parameters);
return source.Where(equalsStatement);
当我执行此操作时,我在Call语句中遇到了MethodInfo的问题。它告诉我;
静态方法需要null实例,非静态方法需要非null实例。
我不是表达树的主人,但我想我理解我在这里做的75%,并且知道我想要实现的目标。 TList现在是个坏名字,但是我从一个可以产生In语句的例子中得到了这个。
我真的在这里寻找解释,所以我可以自己完成代码,或解释我缺少的内容。
编辑:
好的,所以在经历了一个非常令人沮丧的下午之后,我仍然不太明白我完全理解我在做什么,我想我有一个答案。
ParameterExpression sourceObject = Expression.Parameter(typeof(TSource), "x");
Expression<Func<TSource, bool>> check = Expression.Lambda<Func<TSource, bool>>
(
Expression.Equal(
Expression.MakeMemberAccess(sourceObject, typeof(TSource).GetProperty(_sourceProperty)),
Expression.Constant(equalTo)
),
sourceObject
);
return source.Where(check);
有人能够向我解释为什么原件不适合我试图做的事情吗?我想了解更多关于实际过程的信息,但我觉得我并没有像我想的那样快速地接受它。
答案 0 :(得分:3)
Expression.Call有两组重载(每组都有很多重载)。一组是例如方法,另一组是静态方法。在那些静态方法中,第一个参数是一个MethodInfo对象 - 就像你一样。对于实例方法,第一个参数应该是表示目标的表达式(即方法调用中“。”的左侧)。鉴于您收到的错误,它听起来像MethodInfo表示非静态方法,因此您必须提供表示该实例的表达式作为第一个参数。