نکته خیلی مهم : این پست برای مطالعه توصیه نمی شود برای یادگیری LINQ می توانید به " دوره آموزشی LINQ " مراجعه کنید.
یک نکته مهمی که در هنگام استفاده از عملگرهای استاندارد پرس و جو می بایست به آنها توجه داشته باشیم ،خروجی پرس وجو هاست.وقتی یک پرس و جو یک مقدار واحد را برمی گرداند مثل جمع و یا میانگین نتیجه پرس و جو در همان لحظه برگردانده می شود ولی زمانی که خروجی پرس وجو توالی از اطلاعات است ،اجرای پرس و جو به عقب می افتد و ممکن است یک شئ enumerableرا برگرداند
در هنگام تشریح هر یک از عملگرهای استاندارد پرس و جو از سه شئ برای مثال ها استفاده می کنیم که به صورت زیر پیاده سازی می شوند
public class Customer { public int CustomerID; public string Name; public string Address; public string City; public string Region; public string PostalCode; public string Country; public string Phone; public List<Order> Orders; } public class Order { public int OrderID; public int CustomerID; public Customer Customer; public DateTime OrderDate; public decimal Total; } public class Product { public int ProductID; public string Name; public string Category; public decimal UnitPrice; public int UnitsInStock; }
عملگرهای شرطی - Restriction Operators
عملگر Where
این عملگر نتیجه پرس وجو را بر اساس آرگومان ورودی(به عنوان شرط) محدود می کند.فرم کلی این عملگر به صورت زیر است :
public static IEnumerable<T> Where<T>( this IEnumerable<T> source, Func<T, bool> predicate); public static IEnumerable<T> Where<T>( this IEnumerable<T> source, Func<T, int, bool> predicate);
مثال زیر اجناسی که قیمت پایه آنها بیشتر از 10 است برگردانده می شود
IEnumerable<Product> x = from p in products where p.UnitPrice >= 10 select p;
IEnumerable<Product> x = products.Where(p => p.UnitPrice >= 10);
در مثال زیر از فرم دوم عملگرWhere استفاده شده است که خریداری را که اندیس آن در لیست با کد ID آن برابر است ،برمی گرداند
List<Customer> customer = new List<Customer> { New Customer { CustomerID =0,Name =”Ali”}, New Cusyomer { CustomerID =2,name=”Ahmad”}, New Customer { CustomerID =3,name=”Reza”} }; Var query = customer .Where((p,index) => p.CustomerID == index );
توجه کنید اگر آرگومان ها Null باشند یک استثناء ArgumentNullException رخ می دهد.
عملگر OfType
این عملگر اعضاء یک مجموعه را برحسب یک عضو فیلتر می کندprivate static ArrayList GetComplexArrayList () { System.Collections.ArrayList arrList = new System.Collections.ArrayList(4); arrList.Add("String value One"); arrList.Add("String value Two"); arrList.Add("String value Three"); arrList.Add(new Customer { CustomerID =1, Name="ali", Address="Tehran,Islamshahr" }); arrList.Add(new Customer { CustomerID =2, Name="Hossein", Address="Tehran,Vanak"}); arrList.Add(new Order {OrderID = 1 ,CustomerID=1}); return arrList; }
ArrayList arrList = GetComplexArrayList(); // Apply OfType() to the ArrayList. IEnumerable<Customer> query1 = arrList.OfType<Customer>();
عملگرهای پرتو – Projection Oprators
از این عملگرها برای تغییر شکل دادن اعضاء مجموعه ای و انتقال آن (آنها)به مجموعه دیگر استفاده می شود البته می توان اعضاء مجموعه اول را بدون تغییر در مجموعه دوم قرار داد.در ادامه این عملگرها را بررسی می کنیم.عملگر Select
همانطور که در ابتدای این قسمت به عقب افتادن پرس و جو اشاره کردم، نتیجه پرسو جو به عقب می افتد که عملگر Select به این صورت پیاده سازی شده.وقتی یک Select اجرا می شود که بخواهیم نتیجه پرس و جو را با یک foreach مرور کنیم یا متد GetEnumeratorرا صدا بزنیم ،همانطور که در قسمت قبلی به این نکته اشاره کردم وقتی یک حلقه foreach می خواهد یک شئ را پیمایش کند تابع GetEnumerator را فراخوانی می کند تا یک عضو از مجموعه را به دست آورد به همین دلیل است که در حلقه foreach اعضاء فقط خواندنی هستند.این عملگر نیز همانند Where به دو فرم است:
public static IEnumerable<S> Select<T, S>( this IEnumerable<T> source, Func<T, S> selector); public static IEnumerable<S> Select<T, S>( this IEnumerable<T> source, Func<T, int, S> selector);
در مثال زیر نام تمامی مشتریان برگردانده می شود(معادل * در SQL)
List<Customer> customer = new List<Customer> { New Customer { CustomerID =0,Name =”Ali”}, New Cusyomer { CustomerID =2,name=”Ahmad”}, New Customer { CustomerID =3,name=”Reza”} }; IEnumerable<string> customersNames = from itm in customer select itm.Name;
IEnumerable<string> cusyomerNames = customer.Select( itm=> itm.Name);
List<Customer> customer = new List<Customer> { New Customer { CustomerID =0,Name ="Ali"}, New Cusyomer { CustomerID =2,name="Ahmad"}, New Customer { CustomerID =3,name="Reza"} }; Var query = customer.Select( (p,index)=> new{Position=index,p.CustomerID,p.Name});
در مثال زیر نام و دسته اجناسی که قیمتشان از 1000 بیشتر است به عنوان خروجی برگردانده می شود(با فرض اینکه item مجموعه ای از اجناس را در خود دارد)
var querydProduct = items.Where(itm => itm. UnitPrice > 1000) .Select(itm => new { itm.Name, itm. Category }) .ToList(); foreach (var procItem in querydProduct) { Console.WriteLine("The price of {0} is {1}", procItem. Name, procItem.UnitPrice); }
عملگر SelectMany
عملکرد این عملگر همانند Select است ولی امکانی را عرضه تا بتوان چند عملیات را به متصل کرد که می توان آن را روی مجموعه های متفاوتی انجام داد و با حتی از نتیجه پرس و جویی قبلی استفاده کرد. فرم کلی این عملگر به صورت زیر است:
public static IEnumerable<S> SelectMany<T, S>( this IEnumerable<T> source, Func<T, IEnumerable<S>> selector); public static IEnumerable<S> SelectMany<T, S>( this IEnumerable<T> source, Func<T, int, IEnumerable<S>> selector);
var namesAndOrderIDs = customers. Where(c => c.Country == "Iran"). SelectMany(c => c.Orders. Where(o => o.OrderDate.Year == 1389). Select(o => new { c.Name, o.OrderID }) );
var namesAndOrderIDs = from c in customers where c.Country == "Iran" from o in c.Orders where o.OrderDate.Year == 2010 select new { c.Name, o.OrderID };
توصیه : به شما توصیه می کنم که نحوه استفاده از عملگرها بوسیله توابع الحاقی (فرم اصلی) را یاد بگیرید چون کد نویسی را راحت می کند و به نظر بنده یادگیری و به حافظه سپردنشان آسان تر است.
تشکر ویژه بابت مطالبی که مینویسید مخصوصا linq . اگر مثالی در مورد برنامه نویسی چند لایه هم بنویسید خیلی عالی میشه .
پاسخحذفسلام خواهش می کنم
پاسخحذففعلا سرم خیلی شلوغه ولی بعد از پایان مباحث LINQ و Ribbon به مباحثی مانند برنامه نویسی لایه ای و لایه ای باLINQ و مباحث پیشرفته WPF وشاید کمی هم در مورد Asynchronous Event pattern خواهم پرداخت .
موفق باشید،
اقدم.