الدقيقة من التعبيرات Lambda في C #

ما كتبته في المقالة ، مسكت حوالي 10 ساعات ، كان 10 ساعات من التصحيح المستمر ، والتي اختزلت إلى مقارنة تدريجية للإصدارات العاملة وغير العاملة من الكود ، ولا حتى ذلك ، لمقارنة كل سطر من نافذة التصحيح للإصدارات العاملة وغير العاملة من الكود


لمبرمج غير مألوف بأشجار التعبير ، تكشف مقالة تمهيدية جيدة عن msdn بالتفصيل بعض الخطوات في بناء شجرة حذفتها في المقال.


في هذه الحالة ، سيكون هذا الاختبار باللون الأخضر (يتم تمكين الوظيفة الإضافية EF ، حيث يتعطل إذا كان لا يمكن ترجمة الاستعلام بالكامل إلى SQL ).



  • أولاً ، يجب تحديد مناظرة حقل PupilName إذا لم يتم تعريفه ، ولا يتعرف موفر الاستعلام على ما تحتاج خاصية PupilName إلى إسقاطه من أجل إلحاق SQL ORDER BY .
  • ثانياً ، يجب على المزود تحليل هذا التعيين ، على سبيل المثال ، لن ينجح ، سيبدأ EF اليمين (بشكل افتراضي لا يقسم ، فإنه يرفع كيانات في الذاكرة - LINQ إلى كائن ، ولكن يمكن تمكين ذلك ):




والشيء هو أن مزود الاستعلام لا يفهم من خلال خاصية (خصائص) الكيان الذي نريد الفرز. ولكن إذا تمت كتابة التعيين بشكل صحيح ، فسيقوم الموفر بالتعامل مع استعلام SQL وإرساله واستلام استجابة وتصفية النتائج.


في بعض الأحيان يصبح من الضروري كتابة تعبيرات نفسك ، أي شيء مشابه:



سأوضح لك كيفية كتابة هذا التعبير ، إنه ليس بالأمر الصعب ، يقدم الرابط أعلاه عدة أمثلة مماثلة:



نحن نجمع خطوة بخطوة lambda ، أولاً معلمة ، خاصية ، ثم نلصق كل شيء.
في هذه الحالة لن ينجح هذا وسيكون الاختبار باللون الأخضر (لن يتمكن المزود من تحليل التعبير)؟


لا تعرف؟ لا تقلق ، لم أكن أعرف ذلك ، وفي النهاية قضيت حوالي 10 ساعات لفهمه.
هنا تلميح ، هذا سوف يعمل:



يرث PupilDto من PupilDtoBase


الشيء هو أن PropertyInfo يجب أن يؤخذ من الفئة الأساسية إذا كانت الخاصية PupilName نفسها تنتمي إلى الفئة الأساسية ، لذلك C # يبني تعبير lambda ، ويقوم EF بتوزيعها ، بالاعتماد على معايير اللغة


دليل

ما يظهر مصحح الأخطاء إذا كتبت lambda بشكل منتظم في OrderBy :



وفي حالتنا ، مثل هذا:



AutoMapper و IncludeBase


إذا حاولت عدم تكرار الشفرة ، فربما واجهت وراثة DTO و IncludeBase :



هناك موقف أكثر تطوراً:



وسيكون هذا الاختبار أخضر:



والشيء نفسه ، مرة أخرى يتم سحب PropertyInfo من الواجهة:



دليل

تعد الخاصية ReflectedType الخاصة بالعمر واجهة ، حيث يقوم IPupilDto ، C # بإنشاء لامدا ، تكون فيه خاصية Age خاصية لفئة PupilDto ، وليست الواجهة ، ولكن هنا كيف يقوم المصمم التلقائي بإنشاء لامدا:



كيفية حل هذه المشكلة؟ إذا لم يناسبنا IncludeBase Automapper بواجهة (إذا كنت تستخدم التعيين في الذاكرة - لن يؤثر ذلك عليك) ، فسيتعين عليك التخلي عن واجهة برمجة التطبيقات هذه ، لقد حللت هذه المشكلة من خلال تحديد التعيين في طريقة الامتداد ، مثل هذا:



ثم سيجد المصمم التلقائي نفسه خاصية نوع مناسبة بالاسم ، وبناء لامدا "الصحيح"
شكرا لاهتمامكم!

Source: https://habr.com/ru/post/ar453720/


All Articles