سؤال

أحاول كتابة وظيفة ثابتة إلى أو تعبيرين ، لكنني أتلقى الخطأ التالي:

المعلمة "عنصر" ليست في نطاق.

الوصف: حدث استثناء غير معقد أثناء تنفيذ طلب الويب الحالي. يرجى مراجعة تتبع المكدس لمزيد من المعلومات حول الخطأ وأين نشأت في الكود.

تفاصيل الاستثناء: System.InvalIdoperationException: المعلمة "عنصر" ليست في نطاق.

طريقة:

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);
}

تعديل: إضافة المزيد من المعلومات

التعبيرات التي يجري أو تأتي من الطريقة أدناه ، والتي تنفذ على ما يرام. إذا كانت هناك طريقة أفضل أو للنتائج التي أنا جميعها آذان. أيضا ، أنا لا أعرف كم من يجري أو مقدما.

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 (القيد) يعمل على ما يرام عندما يكون القيد من نوع التعبير>. كيف يمكنني أن أفعل أين (crodaint1 أو constraint2) (إلى القيد n'th)

شكرا مقدما!

هل كانت مفيدة؟

المحلول

المشكلة هي أن التعبير الذي تقوم بإنشائه في الطريقة التي يعيد استخدامها في جسم التعبيرين. سوف تحتوي هذه الهيئات على إشارات إلى التعبير parameterexpression الخاص بها الذي تم تعريفه في FilterExpression.

سيكون الإصلاح هو إعادة كتابة الأجزاء اليمنى واليسرى لاستخدام parameterexpression الجديد. أو لتمرير parameterexpression الأصلي على طول. هذا ليس لأن اثنين من 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);
}

يمكنك التكيف مع احتياجاتك والتي لا ترتبط (IMHO) مع LINQ.

لست متأكدًا من المصطلحات المناسبة هنا ، ولكن معلمات التعبير بشكل أساسي ليست متكافئة حتى لو كانت لها نفس الاسم.

هذا يعني أن

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

param1 != param2

لن يكون Param1 و Param2 نفس الشيء إذا تم استخدامه في التعبير.

أفضل طريقة للتعامل مع هذا هي إنشاء معلمة واحدة في المقدمة للتعبير الخاص بك ، ثم تمريرها إلى جميع وظائف المساعد التي تحتاج إلى المعلمة.

تحرير: أيضًا ، إذا كنت تحاول تكوين جمل في LINQ بشكل ديناميكي ProseTbuilder محاولة.

بالنسبة لأولئك الذين عثروا على هذه الصفحة بواسطة محرك بحث وسيستخدمونه The Prosticbuilder من Ben & Joe Albahari, ، احترس ، لأنه لا يعمل مع إطار الكيان.

محاولة هذه النسخة الثابتة في حين أن.

كما حدث حل Fabrizio أيضًا ، لكن نظرًا لأنني كنت أحاول الجمع بين تعبيرين سيتم تنفيذها كاستعلام LINQ 2 SQL ، فقد اعتقدت أنه سيتم تنفيذه في الذاكرة بدلاً من خادم SQL.

لقد كتبت-يدرك LINQ-to-SQL أن الاحتجاج هو تعبير Lambda وبالتالي لا يزال ينتج SQL محسّن.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top