質問

静的関数をOr 2つの式に書き込もうとしていますが、次のエラーを受け取ります:

  

パラメータ「item」はスコープ内にありません。

     

説明:未処理の例外   の実行中に発生した   現在のWeb要求。を確認してください   スタックトレースの詳細については   エラーとその原因   コード。

     

例外の詳細:   System.InvalidOperationException:   パラメーター 'item'はスコープ内にありません。

メソッド:

public static Expression<Func<T, bool>> OrExpressions(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
{
    // Define the parameter to use
    var param = Expression.Parameter(typeof(T), "item");

    var filterExpression = Expression.Lambda<Func<T, bool>>
         (Expression.Or(
             left.Body,
             right.Body
          ), param);
    // Build the expression and return it
    return (filterExpression);
}

編集:さらに情報を追加

orされている式は、以下のメソッドから来ており、うまく実行されます。より良い方法や結果があれば、私はすべて耳にします。また、どれだけの数の人が事前にオアされているかわかりません。

public static Expression<Func<T, bool>> FilterExpression(string filterBy, object Value, FilterBinaryExpression binaryExpression)
{
    // Define the parameter to use
    var param = Expression.Parameter(typeof(T), "item");

    // Filter expression on the value
    switch (binaryExpression)
    {
        case FilterBinaryExpression.Equal:
            {
                // Build an expression for "Is the parameter equal to the value" by employing reflection
                var filterExpression = Expression.Lambda<Func<T, bool>>
                    (Expression.Equal(
                        Expression.Convert(Expression.Property(param, filterBy), typeof(TVal)),
                        Expression.Constant(Value)
                     ),
                    param);
                // Build the expression and return it
                return (filterExpression);
            }

編集:さらに情報を追加

別の方法として、orを実行するより良い方法はありますか?現在、.Where(constraint)は、制約がExpression&gt;型である場合に正常に機能します。 where(constraint1またはconstraint2)(制約n番目まで)を行うにはどうすればよいですか

事前に感謝します!

役に立ちましたか?

解決

問題は、OrExpressionsメソッドで作成しているExpressionが2つの式の本文を再利用することです。これらのボディには、FilterExpressionで定義された独自のParameterExpressionへの参照が含まれます。

修正は、新しいParameterExpressionを使用するように左右の部分を書き換えることです。または、元のParameterExpressionを渡すため。 2つのParameterExpressionが同じ名前を持っているからではなく、同じパラメーターを表します。

他のヒント

すでに提案されているように、こちらには、この非常に優れた(動作する)コードがあります

public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
    var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
    return Expression.Lambda<Func<T, bool>>(Expression.Or(expr1.Body, invokedExpr), expr1.Parameters);
}

ニーズに適応でき、LINQに結び付けられていない(IMHO)。

ここでは適切な用語についてはわかりませんが、基本的に式のパラメーターは同じ名前であっても同等ではありません。

つまり、

var param1 = Expression.Parameter(typeof(T), "item");
var param2 = Expression.Parameter(typeof(T), "item");

param1 != param2

param1とparam2は、式で使用される場合、同じものにはなりません。

これに対処する最善の方法は、式の前に1つのパラメーターを作成し、そのパラメーターを必要とするすべてのヘルパー関数に渡すことです。

編集:また、LINQでwhere句を動的に作成しようとしている場合は、 PredicateBuilder を試してください。

検索エンジンでこのページを見つけて、 Ben&amp; Joe AlbahariのPredicateBuilder を使用する場合は、 Entity Frameworkでは機能しないので注意してください

この修正版を代わりに試してください。

>

Fabrizioの解決策も思いつきましたが、linq 2 sqlクエリとして実行される2つの式を組み合わせようとしたため、sqlサーバーではなくメモリで実行されると考えました。

私は書いた-Linq-To-Sqlは呼び出しがラムダ式であると認識し、最適化されたSQLを生成します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top