تعتمد LINQ في الاستعلامات الخاصة بها على تقنية وهي Deferred Execution (التنفيذ المؤجل) ومعنى هذه التقنية أن الاستعلام لن ينفذ إلا حين يقوم المبرمج بطلب النتائج من الاستعلام.
لاحظ المثال:
static void TryLinq()
{
int i = 0;
int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// fake values for the query only (10 values)
var result = from n in numbers select Increment(ref i);
Console.WriteLine("After query i = {0}", i); // i still 0
Console.WriteLine();
Console.WriteLine("Enumerating results:");
foreach (var v in result)
{
Console.WriteLine("v = {0},\ti = {1}", v, i);
// i is incremented every loop
}
Console.WriteLine("Press any key to continue . . .");
Console.ReadKey(true);
// Result:-
// After query i = 0
//
// Enumerating results:
// v = 1, i = 1
// v = 2, i = 2
// .............
// v = 9, i = 9
// v = 10, i = 10
// What you get?
// Deferred-Execution / Lazy-Execution
// - Query doesn't execute until you begin retrieving it's results.
// - Every time you try get a value the query executes on this value only.
}
static int Increment(ref int i) { return ++i; }نلاحظ في هذا المثال أنه يجب أن يكون المتغير i يساوي 10 (وذلك بعد إضافته كمدخلات للدالة Increment إضافته 10 مرات والتي تزيد عليه 1 كل مرة)
ولكن بعد تنفيذ الأمر تبقى i تساوي 0 كأن الاستعلام لم ينفذ.
أما أثناء عمل loop على النتائج زادت i كل مرة 1.
وذلك هو Deferred Execution.
- الـ Query لا يتم تنفيذها إلا عند طلب النتائج الخاصة بها.
- كل مرة في الـ loop تقوم الـ Query بالتنفيذ فقط على العنصر المطلوب
ولهذا نجد أن العنصر i يزيد كل مرة كأن الـ quey تنفذ كل مرة على عنصر واحد فقط
كيف نقوم بتنفيذ الاستعلام في نفس اللحظة:
static void TryLinq()
{
int i = 0;
int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// fake values for the query only (10 values)
var result = (from n in numbers select Increment(ref i)).ToList();
// The last call tries to get the value immediately.
Console.WriteLine("After query i = {0}", i); // i is 10
Console.WriteLine();
Console.WriteLine("Enumerating results:");
foreach (var v in result)
{
Console.WriteLine("v = {0},\ti = {1}", v, i);
// i still 10 every loop
}
Console.WriteLine("Press any key to continue . . .");
Console.ReadKey(true);
// Result:-
// After query i = 10
//
// Enumerating results:
// v = 1, i = 10
// v = 2, i = 10
// .............
// v = 9, i = 10
// v = 10, i = 10
// What you get?
// Deferred-Execution / Lazy-Execution
// - Query doesn't execute until you begin retrieving it's results.
// - Every time you try get a value the query executes on this value only.
// - You can immediate-execute the query by calling some conversation methods like ToList or ToQuery.
}
static int Increment(ref int i) { return ++i; }نلاحظ في هذا الكود أن استخدامنا لأحد الدالات ToList أو ToArray فإننا بذلك نقوم بطلب تحويل النتائج إلى عنصر من نوع List او مصفوفة Array وبذلك قإننا نطلب من الاستعلام أن ينفذ في نفس اللحظة كي نستطيع تحويله.
وبذلك نجد أن i بعد الاستعلام يكون 10
وأيضا نجد أنه مع عملية loop أن i ثابت على رقم 10.
أرجوا ان أكون قد استطعت الإفادة
لقراءة الموضوع بالكامل: