所以,我正在尝试弄清楚表达式树。我正在尝试添加一个动态等于一个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问题。它告诉我;
静态方法需要空实例,非静态方法需要非空实例。
我不是表达式树的大师,但我认为我理解这里所做的大约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);
有没有人能向我解释一下为什么原始版本不适合我正在尝试做的事情?我想更多地了解实际的过程,但我觉得我没有像我希望的那样快速地掌握它。
发布于 2010-09-12 15:44:06
Expression.Call有两组重载(每组都有很多重载)。例如,一组是方法,另一组是静态方法。在用于静态方法的那些方法中,第一个参数是一个MethodInfo对象--与您的完全一样。例如方法,第一个参数应该是表示目标的表达式(即“”的左侧)。在方法调用中。)考虑到您收到的错误,听起来MethodInfo表示一个非静态方法,因此您必须提供一个表示实例的表达式作为第一个参数。
https://stackoverflow.com/questions/3695235
复制