4

(下面的代码已更新并正常工作)

有来自 LinqPad 的动态 OrderBy 示例。我想要做的只是简单地为这个示例应用“Where”而不是“OrderBy”。这是我的代码:

    IQueryable query =            
    from p in Purchases
    //where p.Price > 100
    select p;

string propToWhere = "Price"; 

ParameterExpression purchaseParam = Expression.Parameter (typeof (Purchase), "p");
MemberExpression member = Expression.PropertyOrField (purchaseParam, propToWhere);

Expression<Func<Purchase, bool>> lambda = p => p.Price < 100;
lambda.ToString().Dump ("lambda.ToString");


//Type[] exprArgTypes = { query.ElementType, lambda.Body.Type };
Type[] exprArgTypes = { query.ElementType };

MethodCallExpression methodCall =
    Expression.Call (typeof (Queryable), "Where", exprArgTypes, query.Expression, lambda);

IQueryable q = query.Provider.CreateQuery (methodCall);
q.Dump();
q.Expression.ToString().Dump("q.Expression");

此代码出现异常:“InvalidOperationException:类型 'System.Linq.Queryable' 上没有方法 'Where' 与提供的参数兼容。”

任何帮助都会被评估。

干杯

4

2 回答 2

4

您的 lambda 表达式创建对我来说看起来很奇怪。您无缘无故地添加了另一个参数。您还使用Predicate<Purchase>而不是Func<Purchase, bool>. 尝试这个:

LambdaExpression lambda = Expression.Lambda<Func<Purchase, bool>>(
                    Expression.GreaterThan(member, Expression.Constant(100)), 
                    purchaseParam);
于 2010-08-06T11:27:24.043 回答
2
  1. 使用 Jon Skeet 提供的 lambda。也许他也可以解释为什么ParameterExpression使用起来如此痛苦并且需要使用相同的实例,而不是能够通过名称匹配:)

  2. 修改这一行:

Type[] exprArgTypes = { query.ElementType };

exprArgTypes是类型参数

IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate).

如您所见,它只有一个类型参数 - TSource,即Purchase. 实际上,您正在做的是Where使用以下两个类型参数调用方法:

IQueryable<Purchase> Where<Purchase, bool>(this IQueryable<Purchase> source, Expression<Func<Purchase, bool>> predicate)

一旦这两个修复程序都在表达式中运行没有问题。

于 2010-08-06T12:03:06.103 回答