InvalidOperationException: метод «Где» для типа «System.Linq.Queryable» не совместим с предоставленными аргументами. - PullRequest
4 голосов
/ 06 августа 2010

(приведенный ниже код был обновлен и работал правильно)

Существует динамический образец OrderBy из LinqPad. Что я хочу сделать, это просто применить «Где», а не «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 »не совместим с предоставленными аргументами.»

Любая помощь оценивается.

Приветствия

Ответы [ 2 ]

4 голосов
/ 06 августа 2010

Твое создание лямбда-выражения выглядит странно для меня. Вы добавляете другой параметр без видимой причины. Вы также используете Predicate<Purchase> вместо Func<Purchase, bool>. Попробуйте это:

LambdaExpression lambda = Expression.Lambda<Func<Purchase, bool>>(
                    Expression.GreaterThan(member, Expression.Constant(100)), 
                    purchaseParam);
2 голосов
/ 06 августа 2010
  1. Используйте лямбду, которую поставил Джон Скит. Возможно, он также может объяснить, почему 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)

Как только оба эти исправления в выражении, запускаются без проблем.

...