مقدمة إلى استعلامات C#) LINQ)
الاستعلام هو تعبير يقوم باسترداد بيانات من مصدر بيانات. غالباً ما يتم التعبير عن استعلامات في لغة استعلام متخصصة. بمرور الوقت، تم تطوير لغات مختلفة لأنواع مختلفة من مصادر البيانات, على سبيل المثال، SQL لقواعد البيانات العلائقية و XQuery لـ XML. لذلك، توجب على المطورين تعلم لغة استعلام جديدة لكل مصدر بيانات أو تنسيق عليهم دعمه. LINQ يبسط هذا الموقف بعرض نموذج متناسق للعمل مع البيانات عبر أنواع عديدة من مصادر البيانات و التنسيقات. في استعلام LINQ، أنت دائماً تعمل مع كائنات. تستخدم نفس أنماط التعليمات البرمجية لاستعلام و تحويل بيانات في مستندات XML، قواعد بيانات SQL، مجموعات بيانات ADO.NET، مجموعات NET. و أي تنسيق يتوفر له موفر LINQ.
ثلاث أجزاء لعملية الاستعلام
كل عمليات الاستعلام LINQ تتكون من ثلاث إجراءات مختلفة:
الحصول على مصدر البيانات.
إنشاء الاستعلام
تنفيذ الاستعلام
المثال التالي يظهر كيفية التعبير عن الأجزاء الثلاثة لعملية الاستعلام في مصدر التعليمات البرمجية. يستخدم المثال صفيف عدد صحيح كمصدر بيانات للملاءمة، و مع ذلك، نفس المفاهيم تنطبق على مصادر بيانات أخرى أيضاً. هذا المثال مشار إليه في بقية هذا الموضوع.
class IntroToLINQ
{
static void Main()
{
// The Three Parts of a LINQ Query:
// 1. Data source.
int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
// 2. Query creation.
// numQuery is an IEnumerable<int>
var numQuery =
from num in numbers
where (num % 2) == 0
select num;
// 3. Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
}
}
الرسم التوضيحي التالي يظهر عملية الاستعلام الكاملة. في LINQ تنفيذ الاستعلام يختلف عن الاستعلام نفسه: بمعنى أخر لا تقوم باسترداد أي بيانات بإنشاء متغير الاستعلام فقط.
مصدر البيانات
في المثال السابق، لأن مصدر البيانات هو صفيف، فهو يدعم واجهة IEnumerable<T> العامة ضمنياً. هذا يعني أنه يمكن استعلامه بواسطة LINQ. ينفذ الاستعلام في عبارة foreach، و foreach يتطلب IEnumerable أو IEnumerable<T>. الأنواع التي تدعم IEnumerable<T> أو واجهة مشتقة مثل IQueryable<T> العامة تسمى أنواع قابلة للاستعلام.
لا تتطلب الأنواع القابلة للاستعلام تعديل أو معاملة خاصة كمصدر بيانات LINQ. إذا كان مصدر البيانات غير موجودة بالفعل في الذاكرة كنوع قابل للاستعلام، يجب أن يعرضه الموفر LINQ على أنه كذلك. على سبيل المثال يقوم مكون LINQ to XML بتحميل مستند XML في نوع XElement قابل للاستعلام:
// Create a data source from an XML document.
// using System.Xml.Linq;
XElement contacts = XElement.Load(@"c:\myContactList.xml");
مع مكون LINQ to SQL، يجب أولاً إنشاء تعيين كائن العلاقات في وقت التصميم إما يدوياً أو باستخدام Object Relational Designer (O/R Designer). تقوم بكتابة الاستعلامات الخاصة بك مقابل الكائنات, وفي وقت التشغيل مكون LINQ to SQL يعالج الاتصالات مع قاعدة البيانات. في المثال التالي، Customer يمثل جدول معين في قاعدة البيانات، و Table<Customer> يدعم IQueryable<T> العام، والتي تشتق من IEnumerable<T>.
// Create a data source from a SQL Server database.
// using System.Data.Linq;
DataContext db = new DataContext(@"c:\northwind\northwnd.mdf");
لمزيد من المعلومات حول كيفية إنشاء أنواع معينة من مصادر بيانات, راجع وثائق موفرات LINQ المتنوعة. ومع ذلك، القاعدة الأساسية بسيطة جدًا: مصدر بيانات LINQ هو أي كائن يدعم واجهة IEnumerable<T> العامة أو واجهة ترث منها.
ملاحظة
أنواع مثل ArrayList التي تدعم واجهة IEnumerable الغير عامة يمكن أيضاً استخدامها كمصدر بيانات LINQ. لمزيد من المعلومات، راجع كيفية القيام بما يلي: استعلام ArrayList مع LINQ.
الاستعلام
يحدد الاستعلام أي المعلومات لاستردادها من مصدر البيانات أو مصادر. بشكل اختياري، يحدد الاستعلام أيضاً كيفية فرز هذه المعلومات، تجميعها و تشكيلها قبل إرجاعها. يتم تخزين الاستعلام في متغير استعلام و تتم تهيئته بواسطة تعبير استعلام. لتسهيل كتابة الاستعلامات ، قدمت #C بناء جملة استعلام جديد.
الاستعلام في المثال السابق يقوم بإرجاع كل الأرقام الزوجية من صفيف الأعداد الصحيحة. يحتوي تعبير الاستعلام على ثلاثة بنود: from ، where و select (إذا كنت معتاداً على SQL، سوف تلاحظ أن ترتيب البنود عكس الترتيب في SQL.) البند from يعين مصدر البيانات، البند where يطبق عامل تصفية, و البند select يعين نوع العناصر المرجعه. تمت مناقشة هذه و بنود الاستعلام الأخرى بالتفصيل في مقطع تعبيرات الاستعلام LINQ (C# البرمجة الدليل). أما الآن، النقطة المهمة هي أن في LINQ، متغير الاستعلام نفسه لايقوم بأي إجراء و لا يرجع أية بيانات. هو فقط يقوم بتخزين المعلومات المطلوبة لتحقيق النتائج عند تنفيذ الاستعلام في وقت لاحق. لمزيد من المعلومات حول كيفية بناء الاستعلامات بالخفاء، راجع نظرة عامة على مشغلات استعلام قياسية.
ملاحظة
يمكن التعبير عن الاستعلامات أيضاً بواسطة استخدام بناء جملة الأسلوب. لمزيد من المعلومات، راجع بناء جملة الاستعلام LINQ مقابل أسلوب البناء (C#).
تنفيذ الاستعلام
تنفيذ مؤجل
كما هو مذكور سابقاً، متغير الاستعلام نفسه يقوم بتخزين أوامر الاستعلام فقط. تم تأجيل تنفيذ الاستعلام الفعلي حتى تكرر عبر متغير الاستعلام في عبارة foreach. يشار إلى هذا المفهوم باسم تنفيذ مؤجل وهو موضّح في المثال التالي:
// Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
العبارة foreach هي أيضاً توجد حيث يتم استرداد نتائج الاستعلام. على سبيل المثال، في الاستعلام السابق متغير تكرار num يقيد كل قيمة (واحدة كل مرة) في التسلسل المرجع.
لأن متغير الاستعلام نفسه لا يحمل أبداً نتائج الاستعلام, يمكنك تنفيذه كلما أردت ذلك. على سبيل المثال، قد يكون لديك قاعدة بيانات يتم تحديثها باستمرار من قبل تطبيق منفصل. في التطبيق الخاص بك، يمكنك إنشاء استعلام واحد يقوم باسترداد البيانات الأحدث، و يمكنك تنفيذه بشكل متكرر في فترات زمنية لاسترداد نتائج مختلفة في كل مرة.
فرض تنفيذ فوري
الاستعلامات التي تقوم بوظائف التجميع خلال نطاق عناصر المصدر يجب أولاً أن تكرر عبر تلك عناصر. أمثلة عن مثل هذه الاستعلامات Count, Max, Average، و First. تنفذ هذه دون عبارة foreach صريحة لأن الاستعلام نفسه يجب أن يستخدم foreach لإرجاع نتيجة. لاحظ أيضاً أن هذه الأنواع من الاستعلامات تقوم بإرجاع قيمة مفردة، ليس مجموعة IEnumerable. الاستعلام التالي يقوم بإرجاع عدد الأرقام الزوجية في الصفيف المصدر:
var evenNumQuery =
from num in numbers
where (num % 2) == 0
select num;
int evenNumCount = evenNumQuery.Count();
لفرض تنفيذ فوري لأي استعلام و تخزين نتائجه مؤقتاً, يمكنك استدعاء الأساليب "ToList<TSource> أو ToArray<TSource>.
List<int> numQuery2 =
(from num in numbers
where (num % 2) == 0
select num).ToList();
// or like this:
// numQuery3 is still an int[]
var numQuery3 =
(from num in numbers
where (num % 2) == 0
select num).ToArray();
يمكنك أيضاً فرض التنفيذ عن طريق وضع التكرار الحلقي foreach مباشرة بعد تعبير الاستعلام. ومع ذلك، باستدعاء ToList أو ToArray أنت أيضاً تقوم بتخزين كل البيانات مؤقتاً في كائن مجموعة مفردة.
راجع أيضًا:
المهام
المرجع
المبادئ
تعبيرات الاستعلام LINQ (C# البرمجة الدليل)