با سلام خدمت کاربران عزیز در این بخش قصد داریم با Filtering Operator (اپراتور های فیلتر) در LINQ آشنا شویم و مثال های متعددی از آن را بررسی کنیم.
در زبان C# برای فیلتر کردن اطلاعات خروجی از Filtering Operator (اپراتور های فیلتر) استفاده می شود.
در LINQ دو نوع متد فیلتر وجود دارد که به شرح زیر می باشند:
کاربرد | نام متد |
از این متد برای انتخاب مقادیری از لیست بر اساس شرایط اعمال شده استفاده می شود | Where |
از این متد برای استخراج نوع داده ای مشخص از لیست استفاده می شود | OfType |
فیلتر Where
مشخص می کند که اطلاعات استخراج شده از منبع داده دارای چه شرطی باشند. بدین صورت که اطلاعات دریافتی باید در شرط موجود در متد where
صدق کنند تا فیلتر اجازه ی عبور آن را صادر کند که کارکرد آن دقیقا مانند Where
در زبان SQL است.
الگوی کلی استفاده از Where
به صورت زیر می باشد:
IEnumerable<string> result = countries.Where(x => x.StartsWith("A"));
برای آشنایی با کاربرد این متد به مثال های زیر توجه کنید:
using System; using System.Linq; using System.Collections.Generic; namespace Linqtutorials { class MainClass { static void Main(string[] args) { string[] countries = { "India", "Iran", "USA", "Argentina", "Peru", "China" }; IEnumerable<string> result = countries.Where(s => s.StartsWith("I")); foreach (string item in result) { Console.WriteLine(item); } Console.ReadKey(); } } }
در این مثال یک آرایه string
که در بردارنده ی نام کشور ها است ایجاد و در ادامه با استفاده از Where
برای استخراج داده از آن، شرطی در نظر گرفته شده که فقط اعضایی انتخاب می شوند که اول نام آن ها I باشد. سپس این اعداد در متغیر result
ذخیره می شوند.
طبق روال قبل این مثال را با روش Query بازنویسی می کنیم که لازم است عبارت جلوی result
را به صورت زیر تغییر دهید:
IEnumerable<string> result = from x in countries where x.StartsWith("A") select x;
مثال اول قسمت قبل را در نظر بگیرید که با استفاده از متد select
نام دانشجو و معدل آن را از لیست خارج و در خروجی چاپ کردیم، حالا قصد داریم فقط نام دانشجوهایی که معدل آن ها بالا تر از 15 است در خروجی نشان دهیم برای این منظور کد را به صورت زیر تغییر می دهیم:
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 = stuList.Where(x =>x.Average>15); 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; } } }
کد را اجرا و خروجی آن را مشاهده کنید و دقت کنید فقط رکوردهایی که معدل آن ها بالای 15 بوده در خروجی نشان داده شده اند. به عبارت Lambda نوشته شده در where
توجه کنید. متغیر x از نوع کلاس Student
و خروجی آن از نوع bool
است. با هدایت موس بر روی where
به راحتی می توانید از صحت این موضوع مطمئن شوید.
برای بازنویسی به صورت Query، کد را به این شکل تغییر می دهیم:
var StudentList = from stu in stuList where stu.Average > 15 select stu;
همان طور که تا اینجا متوجه شدید نوشتن کد به صورت Query ساده تر بوده و تا حدودی شبیه به کدهای SQL است، اما همیشه اینطور نخواهد بود و ممکن است در برنامه های بزرگتر روش Query کمی پیچیده و مشکل به نظر برسد که در آموزش های آینده شاهد این موضوع خواهیم بود.
سوال: آیا می توان در LINQ از شروط چندگانه استفاده کرد؟
جواب: بله. LINQ از شروط چندگانه پشتیبانی می کند و این عملیات به راحتی قابل پیاده سازی است.
به مثال زیر توجه کنید:
using System; using System.Linq; using System.Collections.Generic; namespace Linqtutorials { class MainClass { static void Main(string[] args) { string[] countries = { "India", "Iran", "USA", "Argentina", "Peru", "China" }; IEnumerable<string> result = countries.Where(s => s.StartsWith("I") & s.EndsWith("n")); foreach (string item in result) { Console.WriteLine(item); } Console.ReadKey(); } } }
در اینجا تعین کرده ایم که فقط نام کشور هایی در خروجی نمایش داده شود که شروع با I و پایان آنها با n (کوچک) باشد. توجه داشته باشید که متدهای استفاده شده در where
به کوچک و بزرگ بودن حروف حساس هستد. کد را اجرا و خروجی را مشاهده کنید.
بازنویسی این مثال به روش query به صورت زیر است:
IEnumerable<string> result = from x in countries where x.StartsWith("I") where x.EndsWith("n") select x;
با استفاده از این متد می توان نوع مشخصی از داده را از منبع اطلاعاتی واکشی کنیم، به طوری که بقیه ی عناصر نادیده گرفته شوند.
الگوی استفاده از آن به صورت زیر می باشد:
IEnumerable<string> result = obj.OfType<string>();
توجه کنید که نوع داده ای که قرار است آن را استخراج کنید باید در <>
قرار گیرد.
برای آشنایی با این متد به مثال های زیر توجه کنید:
using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Linqtutorials { class Program { static void Main(string[] args) { ArrayList obj = new ArrayList(); obj.Add("Iran"); obj.Add("USA"); obj.Add(1); obj.Add(true); obj.Add(55.6); obj.Add("UK"); obj.Add("India"); IEnumerable<string> result = obj.OfType<string>(); foreach (var item in result) { Console.WriteLine(item); } Console.ReadLine(); } } }
در این مثال یک ArrayList
تعریف شده که هر نوع داده ای را می توان در آن وارد کرد. حالتی را در نظر بگیرید که فقط به نوع مشخصی از داده های داخل یک منبع نیاز داریم، مثلا نوع string.
برای این منظور متد OfType
در LINQ معرفی شده است. در این مثال نوع های مختلفی از داده در ArrayList
وارد شده اند و ما قصد داریم اعضایی را که نوع آن ها string است، استخراج کنیم.
برای نوشتن با روش Query کد به این صورت تغییر می کند:
IEnumerable result = from x in obj.OfType<int>() select x;
خروجی در حالت انتخاب نوع داده ی string
به شکل زیر است:
مثال جالب زیر را در نظر بگیرید:
using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Linqtutorials { class MainClass { static void Main(string[] args) { ArrayList persons = new ArrayList() { 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}, new Employee(){ ID=2000,Name="nader" ,Gender="Male",HoursWorked=150}, new Employee(){ ID=2000,Name="javad" ,Gender="Male",HoursWorked=177}, new Employee(){ ID=2000,Name="neda" ,Gender="Female",HoursWorked=110}, new Employee(){ ID=2000,Name="arash" ,Gender="Male",HoursWorked=300}, new Employee(){ ID=2000,Name="zahra" ,Gender="Female",HoursWorked=160}, new Employee(){ ID=2000,Name="amin" ,Gender="Male",HoursWorked=100} }; IEnumerable<Employee> personsList = persons.OfType<Employee>().Where(x => x.HoursWorked>140 & x.Gender.Equals("Female")); foreach (Employee item in personsList) { Console.WriteLine("{0}" + "\t" + "{1}"+"\t"+"{2}", item.Name, item.Gender,item.HoursWorked); } 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; } } public class Employee { public int ID { get; set; } public string Name { get; set; } public string Gender { get; set; } public int HoursWorked { get; set; } } }
در این مثال دو کلاس Student
و Employee
تعریف شده که هر کدام دارای فیلد های مشخصی هستد. در کلاس Main
یک ArrayList
تعریف شده و درون آن با اشیای هر دو کلاس پر شده است. هدف اول ما در این مثال استخراج داده هایی از جنس کلاس Employee
است که با استفاده از متد OfType
قابل انجام است. حال قصد داریم فقط کارمندانی که ساعات کاری آن ها بیشتر از 140 ساعت و جنیست آن ها زن است را در خروجی نمایش دهیم که این کار با استفاده شرط داخل Where
قابل پیاده سازی است.
خروجی مثال بالا به صورت زیر است:
zahra Female 160
تمرین: مانند جلسه ی قبل سعی کنید این مثال را با استفاده از روش Query بنویسید و خروجی را با خروجی روش اول مقایسه کنید. بدیهی است که خروجی باید یکسان باشند.
جواب تمرین:
IEnumerable<Employee> personsList = from person in persons.OfType<Employee>() where person.HoursWorked > 140 where person.Gender.Equals("Female") select person;
این بخش از آموزش هم به پایان رسید.
موفق باشید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.