4

(以下のコードは更新され、正しく機能しています)

LinqPadからの動的なOrderByサンプルがあります。私がやりたいのは、このサンプルに「OrderBy」ではなく「Where」を適用することです。これが私のコードです:

    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

あなたのラムダ式の作成は私には奇妙に見えます。明らかな理由もなく、別のパラメータを追加しています。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. JonSkeetが提供したラムダを使用します。おそらく彼は、名前で一致させることができる代わりに、なぜ使用するのがとても苦痛であり、同じParameterExpressionインスタンスを使用する必要があるのか​​を説明することもできます:)

  2. この行を変更します。

Type[] exprArgTypes = { query.ElementType };

exprArgTypesタイプパラメータは

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

ご覧のとおり、タイプパラメータは1つだけです- TSource、ですPurchase。あなたが行っていたのは、事実上、Where以下のような2つの型パラメーターを使用してメソッドを呼び出すことでした。

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

これらの修正の両方が式に含まれると、問題なく実行されます。

于 2010-08-06T12:03:06.103 に答える