عبارت from
عبارت from منبع دادهای که میخواهید دادهای از آن دریافت کنید را تعریف میکند. این عبارت مسئول بدست آوردن عناصر یک منبع داده است. این عبارت در ابتدای یک عبارت پرس وجو میآید، بنا براین کل عبارت پرس و جو پس از آن، نوع دادهای که بر روی آن کار میکنند را میداند. این کار باعث میشود Visual Studio از ویژگی Intellisense بعد از این عبارت بهره مند شود زیرا نوع تک تک اعضای منبع داده را میداند. در زیر شکل کلی این عبارت را مشاهده میکنید :
from dataType rangeVar in dataSource
این عبارت با کلمه کلیدی from شروع میشود که جز Contextual Keywords در سی شارپ است. سپس باید یک متغیر موقت که تک تک اعضای یک مجموعه به ترتیب در آن قرار میگیرند را تعریف کنیم. همچنین شما میتوانید نوع متغیر موقت را صریحاً مشخص کنید که کاربرد خاص خود را دارد. بعد از اعلان متغیر موقت کلمه کلیدی in همراه با نام منبع دادهای که رابط IEnumerable
from int number in numbers
عبارت from بالا به کامپیوتر دستور میدهد که تک تک اعداد داخل یک مجموعه عددی را بر گرداند (با این فرض که آن مجموعه یک آرایه یا شی ای است که رابطIEnumerable را پیاده سازی میکند). به نوع متغیر موقت در مثال بالا توجه کنید. در بیشتر مواقع، اگر از نوع دادههای منبع داده مطمئن هستید میتوانید از نوشتن این نوع صرف نظر کنید.
from number in numbers
کامپایلر میتواند به صورت خودکار و بسته به نوع دادههای منبع داده، نوع متغیر موقت را تشخیص دهد. به عنوان مثال اگر مجموعهای داریم که رابط IEnumerable
1: using System; 2: using System.Linq; 3: using System.Collections; 4: using System.Collections.Generic; 5: 6: namespace FromClause 7: { 8: public class Person 9: { 10: public int PersonId { get; set; } 11: public string FirstName { get; set; } 12: public string LastName { get; set; } 13: public string Gender { get; set; } 14: public int Age { get; set; } 15: 16: public Person(string f, string l) 17: { 18: this.FirstName = f; 19: this.LastName = l; 20: } 21: } 22: 23: class Program 24: { 25: static void Main(string[] args) 26: { 27: ArrayList persons = new ArrayList(); 28: persons.Add(new Person("John", "Smith")); 29: persons.Add(new Person("Mark", "Chandler")); 30: persons.Add(new Person("Eric", "Watts")); 31: 32: var query = from p in persons 33: select p; 34: } 35: } 36: }
اگر مثال بالا را کامپایل کنید با خطای زیر مواجه میشوید :
Could not find an implementation of the query pattern for source type 'System.Collections.ArrayList'. 'Select' not found. Consider explicitly specifying the type of the range variable 'p'.
به این خاطر که ArrayList میتواند شامل اشیاء از نوعهای مختلفی باشد. کامپایلر توصیه میکند که نوع عناصر مجموعه را صریحاً مشخص کنید. برای حل مشکل بالا کافی است نوع متغیر موقت (خط 32) را به شکل زیر مشخص کنید :
from Person p in persons
LINQ برای انجام پرس جو هر کدام از اعضای مجموعه را به نوع Person تبدیل میکند. اگر شی ای از مجموعه پیدا شود که قابل تبدیل به نوع Person نباشد یک استثنا رخ میشود. عبارت from در ابتدای یک عبارت پرس وجو میآید این کار به Visual Studio امکان میدهد که نوع دادههایی که بر روی آنها کار میکنید را تشخیص دهد. همانطور که از شکل زیر پیداست، بعد از عبارت from میتوانید از مزایای Intellisense بهره مند شوید.
وصل کردن چندین جدول از طریق چندین عبارت from
اگر شما 2 منبع داده در اختیار دارید، میتوانید با استفاده از چند عبارت from آنها را به همدیگر وصل کنید. مثال زیر را که باعث اتصال دو مجموعه از اعداد میشود را در نظر بگیرید :
int[] numberSet1 = { 1, 2, 3, 4, 5 }; int[] numberSet2 = { 6, 7, 8, 9, 10 }; var query = from n1 in numberSet1 from n2 in numberSet2 select String.Format("{0},{1}", n1, n2); foreach (var n in query) { Console.WriteLine(n.ToString()); }
(1,6) (1,7) (1,8) (1,9) (1,10) (2,6) (2,7) (2,8) (2,9) (2,10) (3,6) (3,7) (3,8) (3,9) (3,10) (4,6) (4,7) (4,8) (4,9) (4,10) (5,6) (5,7) (5,8) (5,9) (5,10)
در مثال بالا از دو عبارت from که دادهها را از دو منبع مختلف واکشی میکنند استفاده کردهایم. در انتها با استفاده از متد Format خروجی را فرمت بندی کردهایم. همانطور که در خروجی میبینید، هر نوع ترکیب ممکن در خروجی پرس وجو قرار گرفته است (ضرب دکارتی). به این ترکیب اصطلاحاً inner join گفته میشود. همچنین شما میتوانید مستقیماً از عبارت join که بعداً توضیح داده میشود استفاده کنید. به این نکته توجه کنید که لزومی ندارد عبارت from دوم و سوم مستقیماً بعد از عبارت from اول قرار گیرند. شما میتوانید از پرس وجویی به شکل زیر استفاده کنید :
from n1 in numberSet1 where n1 > 2 from n2 in numberSet2 select String.Format("({0},{1})", n1, n2);
یک عبارت from تکی، معادل متدی در فضای نامی System.LINQ ندارد. شما میتوانید از متد Select() و دیگر متدها استفاده کنید. ولی برای چند عبارت from میتوانید از متد SelectMany() که در درسهای بعدی به آن پرداخته میشود استفاده کنید .
ساخت ارتباط بر روی کلاسها
عبارات پرس و جوی متشکل از چند عبارت from میتوانند به شکل موثری در کلاسهای مرتبط استفاده شوند. اما چنین کلاسهایی ابتدا باید به شکل مطلوب ساختار بندی شوند. به عنوان مثال یک مشتری میتواند چندین سفارش داشته باشد که این رابطه را میتوان به عنوان یک رابطه یک به چند در نظر گرفت (یک مشتری با چندین سفارش) اجازه دهید ابتدا کلاس مشتری و سفارش را به شکل مناسب تعریف کنیم :
class Customer { public string FirstName { get; set; } public string LastName { get; set; } public List<Order> Orders { get; set; } }
برای سادگی مثال، کلاس مشتری از 3 خاصیت تشکیل شده است. خاصیت سوم رابطه کلاس مشتری با کلاس سفارش را تعریف میکند. این خاصیت شامل لیست سفارشهای مشتری است. کلاس سفارش در زیر تعریف شده است.
class Order { public string Name { get; set; } public int Quantity { get; set; } }
اجازه دهید چند شیء مشتری ایجاد کرده و چند سفارش را به خاصیت Orders آنها اختصاص دهیم.
1: class Program 2: { 3: static void Main(string[] args) 4: { 5: List<Customer> customers = new List<Customer>(); 6: 7: Customer customer1 = new Customer() 8: { 9: FirstName = "John", 10: LastName = "Smith", 11: Orders = new List<Order>() 12: { 13: new Order() { Name = "Pizza", Quantity = 5 }, 14: new Order() { Name = "Chicken", Quantity = 3 }, 15: new Order() { Name = "Salad", Quantity = 7 } 16: } 17: }; 18: 19: 20: Customer customer2 = new Customer() 21: { 22: FirstName = "Allan", 23: LastName = "York", 24: Orders = new List<Order>() 25: { 26: new Order() { Name = "Orange Juice", Quantity = 2 }, 27: new Order() { Name = "Soda", Quantity = 4 } 28: } 29: }; 30: 31: Customer customer3 = new Customer() 32: { 33: FirstName = "Henry", 34: LastName = "Helms", 35: Orders = new List<Order>() 36: { 37: new Order() { Name = "Speghetti", Quantity = 7 }, 38: new Order() { Name = "Nachos", Quantity = 13 } 39: } 40: }; 41: 42: customers.Add(customer1); 43: customers.Add(customer2); 44: customers.Add(customer3); 45: 46: var results = from c in customers 47: from o in c.Orders 48: select new { c.FirstName, c.LastName, o.Name, o.Quantity }; 49: 50: foreach (var result in results) 51: { 52: Console.WriteLine("Name: {0} {1}, Order: {2}, Quantity: {3}", 53: result.FirstName, result.LastName, result.Name, result.Quantity); 54: } 55: } 56: }
Name: John Smith, Order: Pizza, Quantity: 5 Name: John Smith, Order: Chicken, Quantity: 3 Name: John Smith, Order: Salad, Quantity: 7 Name: Allan York, Order: Orange Juice, Quantity: 2 Name: Allan York, Order: Soda, Quantity: 4 Name: Henry Helms, Order: Speghetti, Quantity: 7 Name: Henry Helms, Order: Nachos, Quantity: 13
همانطور که در خروجی میبینید، سفارشات تمامی مشتریان نشان داده شده است. همچنین برای مرتب کردن خروجی میتوان از عملگر group-by استفاده کرد. در خط 40-7 در مثال قبل، 3 شیء Customer ایجاد کردهایم که هر کدام دارای سفارشات مخصوص به خود هستند. سپس هر کدام از این 3 شیء را به لیست مشتریان اضافه کردهایم. خطوط 48-46 پرس وجویی با 2 عبارت from را نشان میدهد. اولین عبارت from یک شیء Customer را از لیست مشتریان انتخاب میکند. دومین عبارت from تک تک اعضای خاصیت Orders مشتری انتخاب شده را بر میگرداند. عبارت select با استفاده از projection نام و نام خانوادگی مشتری، نام و تعداد سفارش را انتخاب میکند. خطوط 54-50 نتیجه را در خروجی چاپ میکنند.
طراحی کلاسها به شکل بالا بسیار مناسب است زیرا تشخیص ارتباط بین اشیاء به راحتی امکان پذیر است. جداول موجود در پایگاه داده معمولاً از این نوع ارتباطات استفاده میکنند. ابزارهایی در Visual Studio وجود دارند که جدوال و ارتباطات بین آنها را به کلاسها و ارتباط بین آنها تبدیل میکنند. در مبحث LINQ To SQL به این امر پرداخته شده است.
خیلی عالی بود مرسی
خواهش می کنم دوست عزیز…ممنون از اینکه نظر دادین
با سلام ممنون ازتون
استور پروسیجر با LINQ چون کدنویسی کمتری لازم داره.
ممنوم از زحماتتون موفق و موید باشید یه سوال داشتم در مورد لینک با پایگاه داده در سی شارپ روش استفاده استوور پروسیجر با کینک در سی شارپ بهتر است یا از استور پروسیجر در سی شارپ استفاده نکنم کدوم روش را پیشنهاد میکنید؟
سلام ممنون خیلی ساده و روان توضیح میدین اگه امکان داره مطالب این بخش رو زیاد کنید ممنون
سلام دوست عزیز…در حال آماده کردن مطالب جدیدم