سلام با بخش دوم آموزش Linq در C# در خدمت شما عزیزان هستیم. در این جلسه قصد داریم با Projection Operators in LINQ در زبان C# آشنا شویم.
در زبان C# دو نوع Projection Operators وجود دارد:
شرح عملکرد | نوع اپراتور |
با استفاده از این متد می توان محتویات یک منبع داده را واکشی (دریافت) کرد. | select |
با استفاده از این متد می توان اطلاعات را از داخل یک مجموعه به صورت یک مجموعه ای دیگر واکشی کرد. | SelectMany |
برای انتخاب داده ها از یک مجموعه استفاده می شود و کاربرد آن دقیقا مانند select در زبان Sql است.
روش کلی استفاده از آن به صورت زیر می باشد.
var result = from u in userslist select u;
در واقع userslist می تواند هر نوع منبع داده ای باشد که در ادامه در مورد هر کدام بحث خواهد شد. نوع متغییر result بسته به نوع داده ی مورد استفاده می تواند از نوع <>IEnumerable یا <>IQueryable باشد که در بخش های بعدی آموزش مورد بررسی قرار می گیرد؛ فعلا می توانید به جای آن ها از نوع داده ی var استفاده کنید.
برای درک کاربرد select به مثال های زیر توجه کنید.
using System; using System.Collections.Generic; using System.Linq; namespace Linqtutorials { class MainClass { static void Main(string[] args) { List<Student> stuList = new List<Student>() { new Student(){ ID=100,Name="amir",Age=23,Average=16.25}, new Student(){ ID=101,Name="reza",Age=22,Average=12.3}, new Student(){ ID=102,Name="sara",Age=22,Average=12}, new Student(){ ID=103,Name="hassan",Age=24,Average=18}, new Student(){ ID=104,Name="mina",Age=21,Average=17.11}, }; var StudentList = from stu in stuList select stu; Console.WriteLine("name" + "\t" + "average"); foreach (Student item in StudentList) { Console.WriteLine("{0}"+"\t"+"{1}",item.Name,item.Average); } Console.ReadKey(); } } public class Student { public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } public double Average { get; set; } } }
در این مثال یک کلاس Student ایجاد و در متد main یک لیست را با نوع داده ی کلاس Student پر کرده ایم. با استفاده از دستور select
، اطلاعات از داخل آن واکشی شده است و در آخر با استفاده از یک حلقه مقادیر آن در خروجی نمایش داده می شود. توجه داشته باشید که تمامی فیلد های کلاس Student توسط متغیر item قابل دسترسی هستند.
حالا موس را بر روی StudentList نگه دارید تا نوع آن نمایان شود، مشاهده می کنید که نوع آن <IEnumerable<Student
است.
در مثال بالا نحوه ی واکشی اطلاعات تا حدودی شبیه به Sql بود اما این مثال به صورت زیر نیز قابل پیاده سازی است که کافیست قسمت
var StudentList = from stu in stuList select stu;
به
var StudentList = stuList.Select(x => x);
تغییر داده شود، سپس خروحی را دوباره مشاهده کنید خواهید دید که هیچ تفاوتی ندارند.
به مثال دیگری از کاربرد select توجه کنید.
using System; using System.Collections.Generic; using System.Linq; namespace Linqtutorials { class MainClass { static void Main(string[] args) { double[] fnum = { 12.3, 11.5, 18.5, 101.2, 77.5 }; var number = from s in fnum select s; foreach (double item in number) { Console.WriteLine("Num is : {0}",item); } Console.ReadKey(); } } }
در این مثال ساده یک آرایه از نوع double تعریف و برای آن اعضایی در نظر گرفته شده است، سپس با استفاده از select تمامی اعضای آن در متغیر number قرار گرفته اند و با استفاده از یک حلقه تمامی مقادیر قابل پیمایش هستند.
با قرار دادن موس بر روی متغیر number می توانید نوع آن را مشاهده کنید.
مثال بالا به شکل زیر نیز قابل تغییر است.
var number = fnum.Select(f => f);
توجه کنید نام انتخابی برای متغیر Lambda Expressions در داخل متد select دلخواه بوده که در این دو مثال x و f در نظر گرفته شده است.
در این دو مثال تا حدودی با کاربرد select در LINQ آشنا شدید که هر دو مثال جز دسته بندی Linq To Object قرار داشتند. در ادامه به بررسی کاربرد متد SelectMany خواهیم پرداخت.
کاربرد این متد زمانی است که می خواهیم مجموعه ای از داده را از دل یک مجموعه ی دیگر واکشی کنیم. استفاده از این متد باعث کاهش خطوط برنامه و پیچیدگی می شود که در نتیجه ی آن کدها به صورت بهینه نوشته خواهند شد.
به مثال زیر توجه کنید.
using System; using System.Collections.Generic; using System.Linq; namespace Linqtutorials { class MainClass { static void Main(string[] args) { List<Student> Objstudent = new List<Student>() { new Student() { Name = "Ravi Varma", Gender = "Male", Subjects = new List<string> { "Mathematics", "Physics" } }, new Student() { Name = "Vikram Sharma", Gender = "Male", Subjects = new List<string> { "Social Studies", "Chemistry" } }, new Student() { Name = "Harish Dutt", Gender = "Male", Subjects = new List<string> { "Biology", "History", "Geography" } }, new Student() { Name = "Akansha Wadhwani", Gender = "Female", Subjects = new List<string> { "English", "Zoology", "Botany" } }, new Student() { Name = "Vikrant Seth", Gender = "Male", Subjects = new List<string> { "Civics", "Drawing" } } }; var Subjects = Objstudent.SelectMany(x => x.Subjects); foreach (string Subject in Subjects) { Console.WriteLine(Subject); } Console.ReadLine(); } } class Student { public string Name { get; set; } public string Gender { get; set; } public List<string> Subjects { get; set; } } }
همان طور که مشاهده می کنید، در کلاس Student یک فیلد از جنس List قرار دارد و در کلاس main در داخل یک List با نوع داده ی Student چند شی از آن ایجاد کرده ایم. در این مثال قصد داریم مجموعه داده ای (Subjects) را از داخل یک List دیگر استخراج کنیم. کد را اجرا و خروجی را مشاهده کنید.
حالا سعی کنید همین مثال را با استفاده از Select بازنویسی کنید؛ پس SelectMany را به Select تغییر دهید و موس را بر روی متغیر Subjects قرار دهید و نوع داده را مشاهده کنید، خواهید دید که نوع آن <<IEnumerable<List<string
است در صوتی که هنگام استفاده از SelectMany نوع آن به صورت <IEnumerable<string
بود. برای اجرا شدن برنامه با استفاده از متد Select باید کد را به صورت زیر تغییر دهید. در ضمن باقی قسمت ها نیاز به تغییر ندارند:
IEnumerable<List<string>> Subjects = Objstudent.Select(x => x.Subjects); foreach (List<string> Subject in Subjects) { foreach (string s in Subject) { Console.WriteLine(s); } }
به وضوح مشخص است که چگونه متد SelectMany از خطوط برنامه و پیچیدگی آن می کاهد.
حال این مثال را به صورت Query بازنویسی می کنیم که به صورت زیر خواهد بود. توجه کنید که باقی قسمت ها نیاز به تغییر ندارند.
IEnumerable<string> Subjects = from student in Objstudent from st2 in student.Subjects select st2;
در این روش متد SelectMany وجود ندارد و پیاده سازی آن با استفاده از دو select متوالی انجام خواهد گرفت که شباهت زیادی به Select های تودرتو در Sql دارد.
خروجی آن در تمامی موارد به صورت زیر خواهد بود.
به مثال دیگری از کاربرد این متد توجه کنید:
using System; using System.Collections.Generic; using System.Linq; namespace Linqtutorials { class MainClass { static void Main(string[] args) { string[] strigArray = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "0123456789" }; var result = strigArray.SelectMany(s =>s); foreach (char item in result) { Console.Write(item+" "); } Console.ReadKey(); } } }
در این مثال ساده دو عبارت رشته ای در یک آرایه از جنس String قرار دارند، حال قصد داریم اطلاعات موجود در این آرایه که هر کدام حاصل قرار گیری تعدادی کاراکتر هستد را استخراج کنیم. برای بررسی صحت این موضوع موس را بر روی result قرار دهید تا نوع آن نمایش داده شود. کد را اجرا کنید و خروجی را مشاهده کنید، خواهید دید که خروجی به صورت char نمایش داده می شود. برای درک بهتر موضوع می توانید فرض کنید که ابتدا یک Select به آرایه و یک Select به اعضای آن اعمال می کنیم تا به صورت char قابل دسترسی باشند.
برای درک بهتر موضوع تغییرات زیر را در کد اعمال کنید تا تفاوت Select و SelectMany را بهتر متوجه شوید؛ سپس خروجی را با دقت مشاهد کنید:
var result = strigArray.Select(s =>s); foreach (string item in result) { Console.Write(item+" "); }
می بینید که خروجی به صورت دو عنصر String است یعنی دقیقا عناصر موجود در آرایه ی strigArray در خروجی مشاهده می شوند. در واقع در این جا فقط یک select اجرا شده است. در ضمن به نوع متغیر result بار دیگر توجه و با قسمت قبل مقایسه کنید.
به عنوان تمرین این مثال را با استفاده از روشquery بازنویسی (مانند مثال اول) و خروجی را مشاهده کنید.
جواب تمرین
using System; using System.Linq; namespace Linqtutorials { class MainClass { static void Main(string[] args) { string[] strigArray = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "0123456789" }; var result = from str in strigArray from ch in str select ch; foreach (char item in result) { Console.Write(item + " "); } Console.ReadKey(); } } }
می بینید که تنها با یک تغییر کوچک می توان روش گرفتن اطلاعات را تغییر داد که البته نوع متغیر result مانند قبل بوده و هیچ گونه تغییری نخواهد داشت.
این بخش از آموزش به پایان رسید، در بخش بعدی آموزش با Filtering Operator آشنا خواهیم شد و مثال هایی در رابطه با آن حل می کنیم.
موفق باشید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.