محتويات الدورة

C# / المتوسط: التركيب والعمل غير المتزامن / الدرس 8

LINQ والاجتياز المؤجل

توقع توقيت تنفيذ الاستعلام ومايراه وضمانات التحقيق والترتيب الفعلية.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • فصل البناء من الاجتياز.
  • اختيار التحقيق والترتيب عمدا.
  • تمييز IEnumerable من IQueryable المترجمة بمزود.

قدلاينفذ تصريح الاستعلام العمل

توفر LINQ عمليات مركبة. تؤجل Where وSelect على IEnumerable غالبا التنفيذ: لا يجتاز الإنشاء المصدر، بليراه الاجتياز لاحقا. تخزن بعض العمليات داخليا وتنفذ النهائيات فورا. لا يعني أن العامل يعيد IEnumerable أن جميع العمل يحدث عنصرا بعنصر دون تخزين؛ فلكل عامل عقد تنفيذ وكلفة.

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

ملاحظة المصدر عند الاجتياز

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

قديناسب منظورا حيا ويفاجئ من ينتظر نتيجة ملتقطة. وثق صراحة؛ لا توحي تسمية results بلقطة ولا يغير var التوقيت. اختبر ماتعتمد عليه الاستدعاءات. يمكن أن يتغير الاستعلام بين استعمالين حتى عندما لا يعاد إسناد متغيره؛ الذي تغير هو المصدر الذي تقرؤه الوصفة.

csharp يرى الاستعلام المؤجل حالة لاحقة
using System;
using System.Collections.Generic;
using System.Linq;

var source = new List<int> { 1, 2, 3 };
var odd = source.Where(value => value % 2 != 0);
source.Add(5);
Console.WriteLine(string.Join(",", odd));
الناتج المتوقع
1,3,5

تبني Where وصفة وتجتازها string.Join بعد إدراج خمسة.

التحقيق المادي عندما يتطلبه العمر

تجتاز ToArray وToList وتخزنان قيم العناصر فورا. يلتقط المثال قبل التعديل فتبقى المصفوفة1 و3 ويرى الاستعلام5. يفصل الخارج لاكل كائن مرجعي تكراريا. يصبح وقت الالتقاط واضحا عند ToArray، لكن تبقى مراجع العناصر نفسها إن كان النوع قابلا للتعديل.

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

csharp مصفوفة ملتقطة واستعلام حي
using System;
using System.Collections.Generic;
using System.Linq;

var source = new List<int> { 1, 2, 3 };
var query = source.Where(value => value % 2 != 0);
int[] captured = query.ToArray();
source.Add(5);
Console.WriteLine(string.Join(",", captured));
Console.WriteLine(string.Join(",", query));
الناتج المتوقع
1,3
1,3,5

يحدث التحقيق قبل الإضافة والاجتياز الثاني بعدها.

تحديد الترتيب وتجنب التكرار

تحفظ Where ترتيب مصدرها وتثبت OrderBy ترتيب المفتاح بالمقارن. لا يكتسب غير المضمون ترتيبا بالتصفية. اختر Ordinal للبروتوكول وحدد التعادل عند أهمية الخرج، لا ترتيب القاموس العرضي. عند تساوي المفاتيح ينبغي أن يكون الترتيب الخارجي المطلوب محددا بعقد المصدر والعامل أو بمفتاح إضافي.

قدتكرر Count وAny ثمالاجتياز العمل أوتغير الملاحظة. استخدم مرورا أومادية مبررة وتجنب الآثار في الشروط والمحددات. قدتكون حلقة واضحة أفضل مناستعلام كثيف يخفي الكلفة والتعديل. تجنب الاعتماد على أثر شرط ينفذ مرة واحدة؛ قد يعاد تنفيذه كلما أعيد اجتياز الاستعلام.

ترجمة المزود عقد تنفيذ مستقل

قدتمثل IQueryable أشجار تعابير لمزود، بينماتنفذ IEnumerable مفوضات.NET عند الاجتياز. لذاقدتختلف العمليات وnull والأداء والمكان رغم الصياغة. تستخدم الدورة LINQ ذاكرة ولا تدعي استعلام قاعدة مولدا. قد لا يستطيع مزود IQueryable ترجمة كل دالة تعمل في الذاكرة، ويختلف مكان التنفيذ وما يترتب عليه من كلفة.

احتفظ باختبار المزود في تطبيقه. اختبر هنا الفراغ والتكرار وتغير المصدر قبل التنفيذ وشرطا يفشل. سم الواجهات لتوضح المنظور المؤجل والمجموعة الملتقطة عندمايهم العمر. لذلك لا تنقل اختبار LINQ محلي إلى قاعدة بيانات وتعده دليلا على الاستعلام المولد أو سلوكه مع null.

الأخطاء الشائعة وإصلاحها

تتغير نتيجة الواجهة بتغير المصدر.

لماذا يحدث؟
أعادت منظورا مؤجلا لا مجموعة ملتقطة.
كيف تصلحه؟
حقق عند الحد أووثق الحياة.
كيف تتجنب تكراره؟
اختبر التعديل قبل الاجتياز.

يفشل الاستعلام بعدعودة منشئه.

لماذا يحدث؟
تخلص من المورد قبل الاجتياز.
كيف تصلحه؟
اجتز ضمن العمر أونقل الملكية.
كيف تتجنب تكراره؟
راجع التأجيل عبر using.

ينفذ الاستعلام مرورات مكلفة.

لماذا يحدث؟
تجتاز الفحوص النهائية المجهول مرارا.
كيف تصلحه؟
استخدم مرورا أوتحقيقا محدودا.
كيف تتجنب تكراره؟
راجع عدد التنفيذات بالعقد.

اختبر فهمك

1. تعيد طريقة استعلام أسطر مننطاق قارئ مملوك. ماسؤال السلامة؟

اعرض الحل المشروح

حدد مالك الاجتياز ومتىيفتح المورد ويتخلص منه. لا يعتمد المؤجل على قارئ مات عند العودة. اجتز أثناء الملكية وأعد ملتقطا محدودا أوقدم API كسولة يدير مجتازها الفتح والتنظيف. لا تكفي using حول الإنشاء للتكرار اللاحق.

2. لماذا لا تعني ToArray استقلالا عميقا لعناصر Customer متغيرة؟

اعرض الحل المشروح

تنسخ المصفوفة المراجع فيبقى الهدف نفسه. يستقل استبدال الخانة ولا يستقل تعديل Customer. استخدم إسقاطا ثابتا أونسخا صريحا للّقطة الحقلية ووثق السياسة.

أهم ما تعلمته

  • يختلف توقيت البناء والاجتياز والتحقيق.
  • قدتحوي المجموعة المادية كائنات مشتركة.
  • ترجمة المزود ومفوضات الذاكرة عقدان منفصلان.

المراجع الرسمية