كيفية تقييم تعبير منطقي مستقل في شجرة تعبير LINQ
-
07-07-2019 - |
سؤال
أنا أستخدم نمط الزائر القياسي للتكرار من خلال شجرة تعبير LINQ من أجل إنشاء عبارات SQL WHERE الديناميكية.
مشكلتي هي أنه على عكس C#، لا يمكنك استخدام تعبير منطقي مستقل في SQL؛عليك مقارنتها إما بـ 1 أو 0.
بالنظر إلى تعبير لامدا الافتراضي هذا:
h => h.Enabled || h.Enabled == false
سيكون من السهل إنشاء هذا الرمز عن طريق الخطأ:
WHERE Enabled OR Enabled = 0
أو هذا الكود:
WHERE (Enabled = 1) OR (Enabled = 1) = 0
كلاهما بالطبع سيولد خطأ SQL.ما هو المنطق الذي يجب أن أطبقه للتغلب على هذا دون أن يبدأ الكود الخاص بي في الظهور بشكل منفرج حقًا عندما أتعمق في الأشجار الفرعية لمعرفة ماهية الحالة؟
يحرر:المثال أعلاه بالطبع زائد عن الحاجة - أنا أستخدمه فقط لتوضيح نقطة ما.
الأمثلة التي يمكن أن تخلق هذا السيناريو:
h => h.Enabled
h => h.Enabled == enabled
h => h.Enabled == true
من الطبيعي أن المثال الأخير ذو أسلوب رديء، ولكن تم تصميم الكود الخاص بي للعمل بشكل مستقل عن مستوى مهارة المبرمج، لذا فإن عدم تلبية السيناريوهات الزائدة سيكون أمرًا سيئًا من جهتي.
المحلول
الحالات التالية واضحة جدًا:
h => h.Enabled == enabled
h => h.Enabled == true
هؤلاء هم BinaryExpression
العقد، ويمكنك ترجمتها مباشرة إلى:
WHERE (Enabled = @p0)
WHERE (Enabled = 1)
الحالة (الحالات) الخاصة التي تحتاج إلى التعامل معها هي:
h => h.Enabled
h => !h.Enabled
يتم تمثيلها بشكل مختلف في شجرة التعبير (مثل a MemberExpression
).لذلك سوف تحتاج إلى حالة خاصة MemberExpression
وتحديد ما إذا كان يصل إلى خاصية منطقية أم لا.إذا كان الأمر كذلك، فأنت تقوم بترجمته إلى النموذج الأساسي (الكشف عن UnaryExpression
في المثال الثاني):
WHERE (Enabled = 1)
WHERE (Enabled = 0)
وبدلاً من ذلك، قد تتمكن من المعالجة المسبقة لشجرة التعبير وترجمة أي حالات خاصة إلى نموذجها الأساسي (شجرة التعبير).على سبيل المثال، أي MemberExpression
يمكن تحويل العقد التي تناسب المعايير إلى العقد الصحيحة BinaryExpression
.
نصائح أخرى
أليس من الممكن معالجة المعاملات بالكامل قبل تقييم العوامل؟
أي.تقييم كل من:
h => h.Enabled
h => h.Enabled == enabled
h => h.Enabled == true
ل
WHERE (Enabled = 1)
ثم في حالة تضمين عوامل التشغيل في lambda، قم بمعالجة مجموعة المعاملات المقدمة باستخدام SQL المكافئ لتلبية متطلبات عامل التشغيل.