Arabic (العربية/عربي) translation by miahood (you can also view the original English article)
كمطورين للبرامج ، فإننا نقضي الكثير من الوقت في استخراج وعرض البيانات من العديد من مصادر البيانات المختلفة. سواء كانت خدمة ويب XML من نوع ما ، أو قاعدة بيانات علائقية كاملة مميزة ، فقد أجبرنا على تعلم طرق مختلفة للوصول إلى البيانات. ألن يكون رائعًا إذا كانت طريقة الوصول هي نفسها لجميع مصادر البيانات؟ حسنًا ، نحن محظوظون لأنه ، بدءًا من إصدار C # 3.0 و .NET Framework 3.5 ، فقد حان LINQ تغيير اللعبة إلى الأبد.
تفاصيل البرنامج التعليمي
- مقدمة في بناء جملة LINQ
- الإسقاطات باستخدام LINQ
- تنقية البيانات
- المشغلين المعياريين
نظرة عامة على البيانات الحالية
على منصة. NET كنا ومازلنا نستخدم ADO.NET
للوصول إلى مصادر البيانات المختلفة. مجتمع المصدر المفتوح كما قدمت
المطورين مع عدد من البدائل.
استعلام اللغة المتكامل هو الإضافة الجديدة إلى .NET
الأسرة وكما يوحي اسمها هو نوع الوصول إلى نمط بيانات الاستعلام الذي
مدعوم بالكامل من اللغة لتوحيد طريقة الوصول إلى البيانات بشكل فعال
وجعل حياتنا أسهل. LINQ قادرة على استهداف عدد من المصادر المختلفة وهي Oracle ،
MSSQL ، XML ، وعدد قليل من الآخرين ، ولكن الآن سنركز على أبسط من
جميع ، LINQ إلى الكائنات.
LINQ إلى الكائنات
عادة ، لمعالجة وتنقيح البيانات داخل قوائمنا
والعديد من هياكل البيانات الأخرى ، استخدمنا إما حلقة "foreach" أو أخرى
نوع طريقة التكرار للتكرار من خلال الكائنات ومعالجتها بواسطة واحد
واحد وفقا لبعض الشرط. هذا جيد ، ولكن بصراحة يتطلب الكثير من
الترميز الأساسي الذي نتمنى جميعًا ألا نضطر إلى كتابته. في الأساس كان علينا أن نخبر
المجمع كل التفاصيل واحد من العملية من أجل التلاعب في البيانات.
هذا هو بالضبط مكان LINQ يضيء بشكل أفضل. ما LINQ يسمح لنا
ما عليك فعله هو ببساطة إخبار المترجم بما نود القيام به وترك عمل المترجم
أفضل طريقة لتحقيق ذلك. إذا كنت قد استخدمت بناء جملة SQL من قبل ، فإن التشابه الهائل
بين LINQ وأي لهجات SQL سيكون أول ما ستلاحظه.
مثل SQL ، يدعم LINQ أيضًا "select" ، "from"، "where"، "join"، "group by"
و "ترتيب حسب" الكلمات الرئيسية. في ما يلي مثال بسيط للاستعلام عن قائمة من الكائنات:
قائمة التهيئة:
1 |
|
2 |
List<Car> ListOfCars = new List<Car>() |
3 |
{
|
4 |
new Car {name = "Toyota" , owner = "Alex" , model = 1992}, |
5 |
new Car {name = "Mitsubishi", owner = "Jeff" , model = 2005}, |
6 |
new Car {name = "Land Rover", owner = "Danny", model = 2001}, |
7 |
new Car {name = "BMW" , owner = "Danny", model = 2006}, |
8 |
new Car {name = "Subaru" , owner = "Smith", model = 2003} |
9 |
};
|
الاستعلام:
1 |
|
2 |
IEnumerable<Car> QueryResult = from car in ListOfCars |
3 |
select car; |
الجزء الأول من التعليمة البرمجية السابقة يملأ قائمة ببساطة
مع أربعة فئة من فئة "السيارات". الجزء التالي من التعليمات البرمجية ، ومع ذلك ، يستخدم
"من" و "حدد" الكلمات الرئيسية لتحديد مجموعة من الكائنات. الاختلاف الرئيسي
بين SQL و LINQ هو أن الكلمة "من" تأتي قبل "تحديد"
الكلمة الرئيسية لأننا يجب أن نحدد أولاً الكائن الذي نريد العمل عليه. أخيرا
يخبر عبارة "select" المترجم ما نود استخراج في هذا الاستعلام. الأعلى
كود يستخرج كل شيء موجود في القائمة ويعينها إلى "QueryResult"
متغير
عندما نستعلم الأشياء من الأشياء (LINQ إلى كائنات) لدينا
الاستعلامات دوماً بإرجاع قائمة "IEnumrable <T>" من الكائنات. أساسا
نوع "IEnumerable" هو نوع القائمة التي تكشف العداد ، والتي
يدعم التكرار البسيط على مجموعة غير عام ، و <T>
هو نوع كل إدخال في القائمة.
لا تقلق إذا لم تكن على دراية بـ "العدادين" و "الأدوية الجنسية". مجرد
تذكر أن نتيجة استعلامات LINQ هي دائمًا مجموعة مثل البيانات
الهيكل الذي يسمح بالتكرار من خلاله باستخدام حلقة كما هو موضح
أدناه
1 |
|
2 |
foreach(Car car in QueryResult) |
3 |
Console.WriteLine(car.name); |
علمنا أن LINQ دائما إرجاع بنية مجموعة مماثلة
إلى أي قوائم أخرى. ومع ذلك ، لا يتم تنفيذ الاستعلام LINQ حتى نتيجتها
الوصول إليها بواسطة جزء آخر من الشفرة ، مثل حلقة "foreach" أعلاه. هذا هو ل
تسمح لنا باستمرار بتعريف الاستعلام دون النفقات العامة من خلال إعادة تقييم
كل خطوة جديدة في الاستعلام.
التوقعات
حتى الان جيدة جدا؛ ولكن في معظم الأحيان ، ستحتاج استفساراتنا
لتكون أكثر تعقيدًا لذلك دعونا نحاول إسقاط البيانات. في SQL ، يعني الإسقاط الاختيار
اسم العمود (الأعمدة) الخاص بالجدول (الجداول) الذي يرغب في رؤيته يظهر في النتيجة
من الاستعلام. في حالة LINQ إلى كائنات ، سينتج عن أداء الإسقاط
في نوع نتيجة استعلام مختلف عن نوع الكائن الذي نقوم بتنفيذه
الاستعلام على.
هناك نوعان من الإسقاطات التي يمكننا القيام بها. في وسعنا
إما تنفيذ الإسقاط على أساس نوع كائن موجود ، أو الذهاب تماما
الطريقة الأخرى باستخدام أنواع مجهولة. المثال التالي هو الأول
طيب القلب:
1 |
|
2 |
IEnumerable<CarOwner> QueryResult = from car in ListOfCars |
3 |
select new CarOwner { owner_name = car.owner }; |
في التعليمة البرمجية السابقة ، يتم تعريف نوع نتيجة الاستعلام باسم
<CarOwner> ، والذي يختلف عن <Car> ، النوع الذي تتم تهيئة متغير 'ListOfCar' به. نحن لدينا
كما استخدمت الكلمة "الجديدة" وقمت ببعض المهام داخل المجعد
اقواس. في الكود السابق ، يقوم استخدام "select" بالكلمة الأساسية "new" بإخبار
المحول البرمجي لإنشاء كائن جديد "CarOwner" لكل إدخال في نتيجة الاستعلام.
أيضا عن طريق تعيين القيم إلى النوع الجديد قمنا بتهيئة كل مثيل
من فئة "CarOwner".
ومع ذلك ، إذا لم يكن لديك نوع محدد بالفعل
استخدام ، لا يزال بإمكانك تنفيذ الإسقاطات باستخدام أنواع مجهولة.
الإسقاطات باستخدام أنواع مجهول
سيكون من المتاعب الكبيرة ، لو كنت ، بالنسبة لكل إسقاط
اضطر لخلق نوع جديد. هذا هو السبب ، اعتبارا من C # 3.0 ، ودعم Anonymous
تمت إضافة أنواع إلى اللغة. يتم الإعلان عن نوع مجهول باستخدام "var"
الكلمة. يخبر المترجم أن نوع المتغير غير معروف حتى
تم تعيينه لأول مرة.
1 |
|
2 |
var QueryResult = from car in ListOfCars |
3 |
select new { |
4 |
car_name = car.name, |
5 |
owner_name = car.owner |
6 |
};
|
7 |
|
8 |
foreach(var entry in QueryResult) |
9 |
Console.WriteLine(entry.car_name); |
ما ورد أعلاه هو مثال على تنفيذ استعلام مع مجهول
أنواع. الصيد الوحيد الذي يبحث عنه هو أن المجمع لن يقوم بذلك
السماح بإعادة الأنواع المجهولة من الأساليب.
الوصول إلى خصائص نوع مجهول سهل. في Visual Studio 2008 ، الرمز
يسرد إتمام / Intellisense أيضًا الخصائص المكشوفة بواسطة النوع مجهول.



تنقية البيانات
عادة كجزء من استعلام LINQ ، نحتاج أيضًا إلى تحسين
نتيجة الاستعلام عن طريق تحديد الشرط. تمامًا مثل SQL ، تستخدم LINQ أيضًا "أين"
جملة لإخبار المترجم عن الشروط المقبولة.
1 |
|
2 |
IEnumerable<Car> QueryResult = from car in ListOfCars |
3 |
where car.name == "Subaru" |
4 |
select car; |
يوضح التعليمة البرمجية السابقة استخدام جملة "where" و
الشرط لمتابعة. لمزيد من تعريف شروط متعددة ، يدعم LINQ
"و" (&& أمبير) و "أو" (||) يبني. يجب أن يكون الجزء "where" من الاستعلام دائمًا
التعبير المنطقي ، وإلا سيشتكى المترجم.
ترتيب حسب
عند الاستعلام عن الكائنات ، من الممكن الاعتماد على الاستعلام
الهدف يجري فرزها بالفعل. إذا لم يكن هذا هو الحال ، يمكن LINQ رعاية ذلك
باستخدام عبارة "ترتيب حسب" التي ستضمن نتيجة استعلامك
فرزت بشكل صحيح.
1 |
|
2 |
IEnumerable<Car> QueryResult = from car in ListOfCars |
3 |
orderby car.model |
4 |
select car; |
إذا قمت بتشغيل الكود أعلاه ، سترى أن نتيجة
يتم فرز الاستعلام بترتيب تصاعدي. يمكنك تغيير الترتيب باستخدام "تصاعدي" و "تنازلي"
الكلمات الرئيسية ، وكذلك تغيير الترتيب عن طريق تحديد أكثر من حقل واحد للفرز
بواسطة. يوضح التعليمة البرمجية التالية كيف:
1 |
|
2 |
IEnumerable<Car> QueryResult = from car in ListOfCars |
3 |
orderby car.model descending |
4 |
select car; |
تجمع
يسمح LINQ أيضًا بتجميع نتيجة الاستعلام بقيمة
خاصية محددة كما هو موضح في هذا المثال:
1 |
|
2 |
var QueryResult = from car in ListOfCars |
3 |
group car by car.owner into carOwnersGroup |
4 |
select carOwnersGroup.Key; |
كما ترون ، يدعم LINQ جملة "مجموعة بواسطة"
حدد ما هو الكائن وما هي الخاصية التي سيتم تجميعها حسب. الكلمة "إلى" سوف
ثم السماح لنا بالتصميم على نتيجة تجميع يمكن الوصول إليها من خلال "المفتاح"
خاصية.
ينضم
يدعم LINQ الانضمام إلى البيانات من مجموعات مختلفة في مجموعة واحدة
نتيجة الاستعلام. يمكنك القيام بذلك باستخدام الكلمة الأساسية "join" لتحديد الكائنات
للانضمام واستخدام الكلمة الرئيسية "on" لتحديد العلاقة المطابقة بين
الكائنات اثنين.
تهيئة القائمة ذات الصلة:
1 |
|
2 |
List<Car> ListOfCars = new List<Car>() |
3 |
{
|
4 |
new Car {name = "Mitsubishi", owner = "Jeff" , model = 2005}, |
5 |
new Car {name = "Land Rover", owner = "Danny", model = 2001}, |
6 |
new Car {name = "Subaru" , owner = "Smith", model = 2003}, |
7 |
new Car {name = "Toyota" , owner = "Alex" , model = 1992}, |
8 |
new Car {name = "BMW" , owner = "Danny", model = 2006}, |
9 |
};
|
10 |
|
11 |
List<CarOwner> ListOfCarOwners = new List<CarOwner>() |
12 |
{
|
13 |
new CarOwner {owner_name = "Danny", age = 22}, |
14 |
new CarOwner {owner_name = "Jeff" , age = 35}, |
15 |
new CarOwner {owner_name = "Smith", age = 19}, |
16 |
new CarOwner {owner_name = "Alex" , age = 40} |
17 |
};
|
الاستعلام:
1 |
|
2 |
var QueryResult = from car in ListOfCars |
3 |
join carowner in ListOfCarOwners on car.owner equals carowner.owner_name |
4 |
select new {name = car.name, owner = car.owner, owner_age = carowner.age}; |
في الكود أعلاه ، باستخدام نوع مجهول ، انضممنا
وكلاهما في نتيجة استعلام واحدة.
التسلسل الهرمي للكائنات باستخدام Group Joins
حتى الآن ، تعلمنا كيف يمكننا استخدام LINQ لبناء شقة
نتيجة استعلام القائمة. مع LINQ ، من الممكن أيضًا تحقيق استعلام هرمي
النتيجة باستخدام "GroupJoin". بكلمات بسيطة ، يمكننا تعيين الكائنات
خصائص كل إدخال مع استعلام LINQ.
1 |
|
2 |
List<Car> ListOfCars = new List<Car>() |
3 |
{
|
4 |
new Car {name = "Mitsubishi", owner = "Jeff" , model = 2005}, |
5 |
new Car {name = "Land Rover", owner = "Danny", model = 2001}, |
6 |
new Car {name = "Subaru" , owner = "Smith", model = 2003}, |
7 |
new Car {name = "Toyota" , owner = "Alex" , model = 1992}, |
8 |
new Car {name = "BMW" , owner = "Danny", model = 2006}, |
9 |
};
|
10 |
|
11 |
List<CarOwner> ListOfCarOwners = new List<CarOwner>() |
12 |
{
|
13 |
new CarOwner {owner_name = "Danny", age = 22}, |
14 |
new CarOwner {owner_name = "Jeff" , age = 35}, |
15 |
new CarOwner {owner_name = "Smith", age = 19}, |
16 |
new CarOwner {owner_name = "Alex" , age = 40} |
17 |
};
|
18 |
|
19 |
var QueryResult = from carowner in ListOfCarOwners |
20 |
join car in ListOfCars on carowner.owner_name equals car.owner into carsGroup |
21 |
select new {name = carowner.owner_name, cars = carsGroup}; |
22 |
|
23 |
foreach(var carOwner in QueryResult) |
24 |
foreach(var car in carOwner.cars) |
25 |
Console.WriteLine("Owner name: {0}, car name: {1}, car model: {2}", carOwner.name, car.name, car.model); |
في المثال أعلاه ، يتبع عبارة "الانضمام" علامة "إلى"
جزء. هذا يختلف إلى عملية الانضمام السابقة التي نظرنا إليها. هنا ، "إلى"
يتم استخدام جملة لتجميع السيارات من قبل المالك (في carsGroup) وتعيين التجميع إلى
خاصية "السيارات" للنوع المجهول.
مشغلات الاستعلام القياسية
حتى الآن ، تم دعم كل ما رأيناه من قبل C # 3.0
بناء الجملة. ومع ذلك ، لا يزال هناك عدد كبير من العمليات التي لا C # 3.0
الدعم. توفر عوامل تشغيل الاستعلام القياسية إمكانيات الاستعلام بما في ذلك
التصفية والإسقاط والتجميع والفرز وأكثر من ذلك. وبالتالي يتم دعم هذه العمليات
كطرق لمكتبة LINQ ويمكن تنفيذها على نتيجة استعلام كما هو موضح في
لقطة الشاشة التالية:



يتم سرد هذه العوامل أدناه للرجوع اليها.
مشغلي التجميع
- Sum : تقوم بإرجاع مجموع كافة الإدخالات
- ماكس : إرجاع الإدخال بالقيمة القصوى
- Min : إرجاع الإدخال بأقل قيمة
- المتوسط : يعرض متوسط القيمة للمجموعة
- التجميع : يُستخدم لإنشاء تجميع مخصص
- LongCount : عند التعامل مع مجموعة كبيرة ، ستقوم هذه الطريقة بإرجاع قيمة تصل إلى القيمة الأكبر المدعومة من الفئة "الطويلة"
- Count : إرجاع "عدد صحيح" لعدد العناصر في المجموعة
مشغلي العناصر
- أولاً : إرجاع الإدخال الأول من مجموعة النتائج
- FirstOrDefault : إذا كانت المجموعة الفارغة ، ستقوم بإرجاع القيمة الافتراضية ، وإلا فسيتم إرجاع الإدخال الأول من المجموعة
- مفرد : سيعود فقط بالعنصر من المجموعة
- SingleOrDefault : إذا كانت المجموعة الفارغة ، ستقوم بإرجاع القيمة الافتراضية ، وإلا فسيتم إرجاع العنصر فقط من المجموعة
- الأخير : إرجاع الإدخال الأخير من المجموعة
- LastDrDefault : إذا كانت المجموعة الفارغة ، ستُرجع القيمة الافتراضية ، وإلا ستُرجع آخر إدخال من المجموعة
- ElementAt : إرجاع العنصر في الموضع المحدد
- ElementAtOrDefault : إذا كانت المجموعة الفارغة ، ستقوم بإرجاع القيمة الافتراضية ، وإلا ستقوم بإرجاع العنصر في الموضع المحدد
مجموعة المشغلين ذات الصلة
- باستثناء : على غرار الانضمام إلى اليسار في SQL ، سيتم عرض إدخالات من مجموعة واحدة غير موجودة في مجموعة أخرى
- الاتحاد : إرجاع كافة الإدخالات من كلا الكائنات
- التقاطع : إرجاع نفس العناصر من أي من المجموعتين
- متميز : إرجاع إدخالات فريدة من المجموعة
مشغلي الجيل
- mpletion/Intellisense also lists the properties exposed by the Anonymous type.
- التكرار : يكرر عند إرجاع الكائنات لعدد محدد من المرات
- فارغ : سيعود مجموعة IEnumerable فارغة
- نطاق : إرجاع نطاق من الأرقام لرقم بدء محدد وعدد
تكرير المشغلين
- المكان : سيُرجع الكائنات التي تستوفي الشرط المحدد
- OfType : سيتم إرجاع الكائنات من النوع المحدد
مشغلي التحويل
- ToLookup : إرجاع النتيجة على أنها بحث
- ToList : إرجاع النتيجة كمجموعة قائمة
- ToDictionary : يعرض النتيجة كقاموس
- ToArray : إرجاع النتيجة كمجموعة صفيف
- AsQueryable : تقوم بإرجاع النتيجة كـ IQueryable <T>
- AsEnumerable : إرجاع النتيجة كـ IEnumerable <T>
- OfType : تقوم بتصفية المجموعة وفقًا للنوع المحدد
- Cast : يُستخدم لتحويل مجموعة مطبوعة بشكلٍ ضعيف إلى مجموعة مطبوعة بكثرة
تقسيم المشغلين
- أخذ : إرجاع عدد محدد من السجلات
- Takewhile : إرجاع عدد محدد من السجلات أثناء تقييم الشرط المحدد إلى true
- تخطي : يتخطى العدد المحدد من الإدخالات ويعيد الباقي
- SkipWhile : يتخطى العدد المحدد من الإدخالات أثناء تقييم الشرط المحدد إلى true
مشغلي Quantifier
- أي : إرجاع true أو false لحالة محددة
- يحتوي على : إرجاع true أو false لوجود الكائن المحدد
- الكل : يعرض true أو false لجميع الكائنات التي تستوفي الشرط المحدد
الانضمام إلى المشغلين
- Join : إرجاع الإدخالات حيث المفاتيح في مجموعات هي نفسها
- GroupJoin : يُستخدم لإنشاء كائنات هرمية استنادًا إلى علاقة رئيسية وتفصيلية
مشغلو المساواة
- إرجاع SequenceEqual : true عندما تكون المجموعات متساوية
فرز المشغلين
- عكس : إرجاع مجموعة معكوس
- ThenBy : تستخدم لأداء مزيد من الفرز
- ThenByDescending : يستخدم لأداء مزيد من الفرز بترتيب تنازلي
- OrderBy : تستخدم لتعريف النظام
- OrderByDescending : يستخدم لتحديد ترتيب تنازلي
مشغلي الإسقاط
- SelectMany : تستخدم لتسوية مجموعة هرمية
- اختر : يستخدم لتحديد الخصائص للعودة
مشغلي التسلسل
- كونكات : تستخدم لسلسلتي مجموعتين
ماذا الآن؟
لقد أثبتت LINQ أنها مفيدة للغاية في الاستعلام عن الأشياء ، كما أن بناء الجملة على شكل SQL يجعلها سهلة
تعلم والاستخدام. أيضا ، فإن العدد الكبير من المشغلين المعياريين يجعل من الممكن سلسلة عدد من المشغلين
لتنفيذ الاستعلامات المعقدة. في متابعة هذا البرنامج التعليمي ، سنقوم بمراجعة كيفية استخدام LINQ
قواعد بيانات الاستعلام ومحتوى XML ..
بيع البرامج النصية. NET ومكونات على CodeCanyon
- تابعنا على Twitter ، أو اشترك في Netsuts + RSS Feed للحصول على أفضل البرامج التعليمية لتطوير الويب على الويب.