اندازهی قلم متن
تخمین مدت زمان مطالعهی مطلب:
پنج دقیقه
در ادامه سری آموزشی LINQ، موارد دیگری از عبارتهای پرس و جو را بررسی میکنیم:
• عبارت group
• عبارت orderby
• کلمات کلیدی ascending و descending
• کلمه کلیدی by
بررسی عبارت group و کلمهی کلیدی by
عبارت group یک توالی یک بعدی (flat sequence) یا ساده را از ورودی دریافت و یک توالی گروه بندی شده را تولید میکند.
برای آشنایی بیشتر با اینترفیس IGrouping اینجا را مطالعه کنید.
عبارت orderby و کلمات کلیدی ascending و descending
عبارت orderby برای تولید یک توالی مرتب شدهی بصورت صعودی (ascending) و یا نزولی (descending) مورد استفاده قرار میگیرد.
مثال: توالی مثال قبل را در نظر بگیرد:
خروجی مثال بالا:
علملیات مرتب سازی بصورت پیش فرض بصورت صعودی میباشد (Ascending). برای تغییر این حالت میتوانید از کلمهی کلیدی descending استفاده کنید:
با اجرای مجدد برنامه، خروجی زیر را مشاهده خواهید کرد:
خروجی مثال بالا :
همانطور که مشاهده میکنید بر عکس حالت قبلی که خروجی گروهها بصورت نزولی بود، اینجا خروجی بر اساس کالری غذا و بصورت صعودی، نمایش داده شده است.
در این سری آموزشی با دو روش نوشتن پرس و جو، در LINQ آشنا شدیم:
1- Fluent Style (استفاده از متدهای الحاقی برای انجام عملیاتهای مختلف بر روی توالی)
2- Expression Style (استفاده از کلمات کلیدی (key word) برای انجام عملیاتهای مختلف بر روی توالی)
هر یک از روشهای فوق مزایایی دارند که با توجه به شرایطی که با آن روبرو هستیم از آنها استفاده میکنیم:
در مثال فوق نتیجهی اجرای دو پرس و جو، موادی است که کالری آنها بیشتر از 100 میباشد. همانطور که مشاهده میکنید روش اول مختصرتر از روش دوم است. این مورد در زمانی است که تنها یک عملیات بر روی توالی اجرا شود.
• پرس و جویی که قرار است نوشته شود، از نظر عملیات بر روی توالی ساده باشد: در این حالت روش استفاده شده تفاوتی نمیکند و بستگی به روش برگزیده و مورد علاقهی برنامه نویس و یا تیم برنامه نویسی دارد. مثلا زمانیکه تنها عملگرهای Where و orderby بخواهند اجرا شود.
• پرس و جوهایی که با متغیرهای range مختلفی رو برو هستند: در این حالت استفاده از عبارتهای پرس و جو راحت از روش عملگرهای پرس و جو میباشد.
لیستی از عملگرهای جستجو که در روش عبارتهای جستجو معادل آنها مهیا شده است :
• GroupBy
• GroupJoin
• Join
• OrderBy
• OrderByDescending
• Select
• SelectMany
• ThenBy
• ThenByDescending
• Where
در بسیاری از پرس و جوها میتوانیم هر دو روش را با هم ترکیب کنیم که نمونهای از آن، در جلسهی چهارم در زمان استفادهی از متد DefaultIfEmpty استفاده شد. درمثال زیر استفاده از عملگر count، با استفاده از روش اول، به همراه عبارت پرس و جوی تولید شدهی با روش دوم، نمایش داده شده است:
• عبارت group
• عبارت orderby
• کلمات کلیدی ascending و descending
• کلمه کلیدی by
بررسی عبارت group و کلمهی کلیدی by
عبارت group یک توالی یک بعدی (flat sequence) یا ساده را از ورودی دریافت و یک توالی گروه بندی شده را تولید میکند.
مثال: در بخش دوم این سری آموزشی، کلاسی به نام Ingredient تعریف کردیم که مواد غذایی و کالری آنها را نگهداری میکرد. در این مثال قصد داریم مواد غذایی دریافت شده از توالی ورودی را بر اساس کالری آنها، به گروههایی تقسیم کنیم، بطوریکه مواد غذایی با کالریهای یکسان در یک گروه قرار بگیرند:
Ingredient[] ingredients = { new Ingredient{Name = "Sugar", Calories=500}, new Ingredient{Name = "Lard", Calories=500}, new Ingredient{Name = "Butter", Calories=500}, new Ingredient{Name = "Egg", Calories=100}, new Ingredient{Name = "Milk", Calories=100}, new Ingredient{Name = "Flour", Calories=50}, new Ingredient{Name = "Oats", Calories=50} }; IEnumerable<IGrouping<int, Ingredient>> query = from i in ingredients group i by i.Calories; foreach (IGrouping<int, Ingredient> group in query) { Console.WriteLine($"Ingredients with {group.Key} calories"); foreach (Ingredient ingredient in group) { Console.WriteLine($"- { ingredient.Name}"); } }
در این مثال، از نوع جنریکی به نام IGrouping استفاده شدهاست که اولین پارامتر آن کلید گروه است (در این مثال کالری مواد غذایی) و دومین پارامتر آن، نوع لیست را مشخص میکند که در اینجا کلاس Ingredient است. اعضای لیست تولید شده، کالری یکسانی دارند. دلیل استفادهی از نوعها بصورت صریح و آشکار (Explicit) خوانایی بیشتر برای تشخیص خروجیهای تولید شدهی در کدها میباشد. ولی راه بهتر، جایگزین کردن کد <<IEnumerable<IGrouping<int, Ingredient با کلمهی کلیدی var میباشد.
خروجی مثال بالا:Ingredients with 500 calories - Sugar - Lard - Butter Ingredients with 100 calories - Egg - Milk Ingredients with 50 calories - Flour - Oats
برای آشنایی بیشتر با اینترفیس IGrouping اینجا را مطالعه کنید.
عبارت orderby و کلمات کلیدی ascending و descending
عبارت orderby برای تولید یک توالی مرتب شدهی بصورت صعودی (ascending) و یا نزولی (descending) مورد استفاده قرار میگیرد.
مثال: توالی مثال قبل را در نظر بگیرد:
IOrderedEnumerable<Ingredient> sortedByNameQuery = from i in ingredients orderby i.Name select i; foreach (var ingredient in sortedByNameQuery) { Console.WriteLine(ingredient.Name); }
Butter Egg Flour Lard Milk Oats Sugar
IOrderedEnumerable<Ingredient> sortedByNameQuery = from i in ingredients orderby i.Name descending select i;
Sugar Oats Milk Lard Flour Egg Butter
عبارت orderby را میتوان با عبارت groupby ترکیب کرد و نتیجهی حاصل از مثال اول این مطلب را بصورت مرتب شده بر اساس کالری مواد غذایی مشاهده کرد.
مثال: Ingredient[] ingredients = { new Ingredient{Name = "Sugar", Calories=500}, new Ingredient{Name = "Lard", Calories=500}, new Ingredient{Name = "Butter", Calories=500}, new Ingredient{Name = "Egg", Calories=100}, new Ingredient{Name = "Milk", Calories=100}, new Ingredient{Name = "Flour", Calories=50}, new Ingredient{Name = "Oats", Calories=50} }; IEnumerable<IGrouping<int, Ingredient>> query = from i in ingredients group i by i.Calories into calorieGroup orderby calorieGroup.Key select calorieGroup; foreach (IGrouping<int, Ingredient> group in query) { Console.WriteLine($"Ingredients with {group.Key} calories"); foreach (Ingredient ingredient in group) { Console.WriteLine($"- { ingredient.Name}"); } }
Ingredients with 50 calories - Flour - Oats Ingredients with 100 calories - Egg - Milk Ingredients with 500 calories - Sugar - Lard - Butter
در این سری آموزشی با دو روش نوشتن پرس و جو، در LINQ آشنا شدیم:
1- Fluent Style (استفاده از متدهای الحاقی برای انجام عملیاتهای مختلف بر روی توالی)
2- Expression Style (استفاده از کلمات کلیدی (key word) برای انجام عملیاتهای مختلف بر روی توالی)
هر یک از روشهای فوق مزایایی دارند که با توجه به شرایطی که با آن روبرو هستیم از آنها استفاده میکنیم:
• تعداد عملگرها : در صورتی که پرس و جو نیاز به یک عملگر بر روی توالی داشته باشد میتوان از روش اول استفاده کرد. به این خاطر که نسبت به روش دوم تعداد دستورات کمتری مورد استفاده قرار خواهد گرفت.
مثال :var q1 = ingredients.Where(x => x.Calories > 100); var q2 = from i in ingredients where i.Calories > 100 select i;
• پرس و جویی که قرار است نوشته شود، از نظر عملیات بر روی توالی ساده باشد: در این حالت روش استفاده شده تفاوتی نمیکند و بستگی به روش برگزیده و مورد علاقهی برنامه نویس و یا تیم برنامه نویسی دارد. مثلا زمانیکه تنها عملگرهای Where و orderby بخواهند اجرا شود.
• پرس و جوهایی که با متغیرهای range مختلفی رو برو هستند: در این حالت استفاده از عبارتهای پرس و جو راحت از روش عملگرهای پرس و جو میباشد.
لیستی از عملگرهای جستجو که در روش عبارتهای جستجو معادل آنها مهیا شده است :
• GroupBy
• GroupJoin
• Join
• OrderBy
• OrderByDescending
• Select
• SelectMany
• ThenBy
• ThenByDescending
• Where
در بسیاری از پرس و جوها میتوانیم هر دو روش را با هم ترکیب کنیم که نمونهای از آن، در جلسهی چهارم در زمان استفادهی از متد DefaultIfEmpty استفاده شد. درمثال زیر استفاده از عملگر count، با استفاده از روش اول، به همراه عبارت پرس و جوی تولید شدهی با روش دوم، نمایش داده شده است:
int mixedQuery = (from i in ingredients where i.Calories > 100 select i).Count();