در توسینسو تدریس کنید

و

با دانش خود درآمد کسب کنید

آموزش LINQ در سی شارپ :: قسمت 1 - آشنایی با LINQ

در طول یکسری مقاله قصد دارم تا شما را با Language Integrated Query یا LINQ و کاربردهای آن در زبان #C آشنا کنم. این ویژگی که به شما قابلیت اجرای کوئری های مختلف از داخل زبان #C را می دهد که با ارئه نسخه 3 از زبان #C معرفی شد.

مقدمه


سر فصل های مقالات به طور خلاصه به شرح زیر می باشد:

  1. مقدمه ای بر LINQ و ویژگی های آن
  2. ویژگی های جدید 3.0 #C
  3. ساختار کوئری های LINQ و نحوه اجرای کوئری ها
  4. آشنایی با عملگرهای استاندارد در کوئری های LINQ (بخش اول)
  5. آشنایی با عملگرهای استاندارد در کوئری های LINQ (بخش دوم)
  6. آشنایی با عملگرهای استاندارد در کوئری های LINQ (بخش سوم)
  7. آشنایی با عملگرهای استاندارد در کوئری های LINQ (بخش چهارم)
  8. LINQ to XML
  9. آشنایی با LINQ to Entities
  10. LINQ to Provider
  11. پروژه عملی


به طور خلاصه در هر کدام از این بخش ها چه مطالبی مطرح خواهد شد؟

1. در این بخش با ایجاد یک پروژه ساده مروری کوتاه بر یک کوئری ساده LINQ خواهیم داشت. همچنین با نحوه نوشتن کوئری ها قبل از ارائه LINQ آشنا خواهیم شد. در انتهای این بخش نیز با انواع Provider های موجود برای LINQ به طور خیلی خلاصه آشنا خواهیم شد.


2. بدلیل آنکه بسیاری از ویژگی های جدید معرفی شده در #C نسخه 3، جهت ایجاد کوئری های LINQ است، در این بخش با این ویژگی ها بیشتر آشنا خواهیم شد تا بعد ها بتوانیم از آنها در نوشتن کوئری های پیچیده تر استفاده کنیم.

3. در این بخش با ساختار کلی کوئری های LINQ و همچنین نحوه اجرای کوئری ها آشنا خواهیم شد.

4 الی 7. در این چهار بخش اپراتورهای استاندارد LINQ را مورد بررسی قرار خواهیم داد، برای مثال اپراتور های مربوطه برای فیل تر کردن اطلاعات، مرتب سازی، گروه بندی و ... . (به دلیل حجم زیاد این اپرداتور ها توضیحات مربوطه به چهار بخش تقسیم شده اند)

8. در این بخش ابتدا مقدمه کوتاهی بر نحوه استفاده از XML در #C خواهیم داشت و سپس با کوئری های LINQ to XML که قابلیت گرفتن کوئری از مستندات XML را به ما می دهد آشنا خواهیم شد.

9. می توان گفت که این بخش اصلی ترین بخش مورد بحث ما خواهد بود و بخش زیادی از مقاله به این بخش اختصاص خواهد داشت. در این بخش با قابلیت اجرای کوئری های LINQ بر روی بانک های SQL Server آشنا خواهیم شد.

10. بخش بعدی این مقاله به مبحث ایجاد Provider دلخواه برای کوئری های LINQ اختصاص دارد که یکی از مباحث پیچیده و پیشرفته LINQ می باشد. برای مثال در LINQ to SQL، کلمه SQL نشان دهنده Provider مربوطه برای کوئری های لینک است که از این Provider برای بانک های SQL Server استفاده می شود. در این بخش با نحوه ایجاد یک Provider دلخواه برای کوئری های LINQ آشنا خواهیم شد.

11. در بخش نهایی این مقاله به ایجاد یک پروژه عملی خواهیم پرداخت تا با ویژگی های کاربردی LINQ بهتر آشنا شویم. این پروژه بر اساس ساختار سه لایه پیاده سازی خواهد شد.

در طول مقاله فرض کردم که دوستان با مفاهیم زیر آشنایی دارند:

1. مقدمات زبان #C
2. برنامه نویسی شئ-گرا و مفاهیم آن
3. جنریک ها و کلاس های مجموعه ای
4. اینترفیس ها
5. طراحی و پیاده سازی بانک های اطلاعاتی در SQL Server

تمام کدهای ارائه شده در این مقاله با زبان #C نوشته می شوند. همچنین پس از اتمام مقاله نسخه PDF این مقاله به همراه کدهای #C در اختیار کاربران انجمن قرار خواهد گرفت.

مقدمه بر LINQ

در ادامه مقدمه ای بر LINQ خواهیم داشت و همچنین با قابلیت ها و توانایی های آن به صورت مختصر آشنا خواهیم شد.
شاید اولین سوالی که در ذهن هر یک از شما پیش بیاد این باشه که چه تعریفی می توان برای LINQ ارائه داد؟ چه کارهایی می توان با LINQ انجام داد؟ LINQ چه قابلیت هایی را در اختیار یک برنامه نویس قرار می دهد؟ به این سوالات می شود به این صورت جواب داد که LINQ شامل یکسری عملگرهای استاندارد است که به شما امکان می دهد بر روی انواع منابع داده در داخل زبان های سازگار با NET. مانند VB.NET یا #C کوئری هایی را نوشته و اجرا کنید. نام Language Integrated Query نیز به این دلیل انتخاب شده است که این کوئری ها داخل یک زبان برنامه نویسی مانند #C نوشته و اجرا می شوند. اما منابع داده ای که LINQ می تواند از آنها استفاده کند می تواند یک شئ ایجاد شده، یک فایل مستندات XML، یک بانک SQL Server و یا یک منبع دلخواه باشد. LINQ این قابلیت را دارد که با تمامی این منابع داده کار کند. علاوه بر استخراج و اجرای کوئری بر روی منابع داده نیز، بوسیله LINQ شما امکان تغییر و دستکاری یک منبع داده مانند یک بانک SQL Server را خواهید داشت. برای شروع با یک مثال کوچک شروع میکنیم:

فرض کنید که یک آرایه از نوع رشته داریم که یکسری نام را داخل آن قرار دادیم، حالا می خواهیم نام هایی که با حروف Mo شروع می شوند را جستجو کرده و به کاربر نمایش دهیم. برای اینکار باید یک آرایه ایجاد کرده و با یک دستور foreach بر روی تک تک عناصر آرایه عملیات مقایسه را انجام داده و نتیجه را به کاربر نشان دهیم:

string[] names = { "Ali", "Hasan", "Mojtaba", "Hamid", "Morteza", "Reza", "Mohammad" };
foreach (string name in names)
if(name.StartsWith("Mo"))
Console.WriteLine(name);


با اجرای کد بالا تمامی نام هایی که با حروف Mo شروع می شوند در خروجی چاپ خواهند شد. اما اینکار را می توان با نوشتن یک کوئری بسیار ساده LINQ نیز انجام داد. قطعه کد زیر یک کوئری LINQ است که نام هایی که با Mo شروع می شوند را برای ما استخراج کرده و بر روی خروجی نمایش میدهد:

string[] names = { "Ali", "Hasan", "Mojtaba", "Hamid", "Morteza", "Reza", "Mohammad" };
IEnumerable query = from n in names
where n.StartsWith("Mo")
select n;
foreach (string name in query)
Console.WriteLine(name);


در کد بالا دستوراتی وجود دارد که شاید با آنها نا آشنا باشید، اما نگران نباشید، در ادامه این مقاله با تک تک دستورات بالا و کاربرد هر یک آشنا خواهید شد. اما مهمترین چیزی که در دستورات بالا توجه یک برنامه نویس را به خود جلب میکند، شباهت ساختار کوئری نوشته شده با کوئری های SQL است. وقتی این کوئری اجرا می شود یک شئ از نوع اینترفیس <IEnumerable
برای مقایسه عملگرهای LINQ با دستوراتی که قبلا" برای گرفتن کوئری ها از اشیاء استفاده می شد، به سراغ کلاس <List

public class Person
{
public Person() { }
public Person(string firstName, string lastName, int age)
{
this.FirstName = firstName;
this.LastName = lastName;
this.Age = age;
}

public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }

public override string ToString()
{
return string.Format("FirstName: {0}\n{LastName: {1}\nAge: {2}", this.FirstName, this.LastName, this.Age);
}
}


کلاس بالا شامل سه فیلد، دو متد سازنده و متد override شده ToString است. در قدم بعدی ما یک لیست از اشیاء Person ایجاد میکنیم. (<List

List persons = new List()
{
new Person() { FirstName = "Ali", LastName = "Jamali", Age = 42 },
new Person() { FirstName = "Hosein", LastName = "Ahmadi", Age = 23 },
new Person() { FirstName = "Mohamamd", LastName = "Sadeghi", Age = 17 },
new Person() { FirstName = "Reza", LastName = "Jamali", Age = 24 },
new Person() { FirstName = "Nima", LastName = "Karami", Age = 18 }
};


حال می خواهیم از مجموعه بالا تمامی افرادی که سنشان زیر 20 سال است را انتخاب کرده و در خروجی نمایش دهیم. کلاس <List

List query = persons.FindAll(delegate(Person p) { return p.Age < 20; });
foreach (Person person in query)
{
Console.WriteLine(person.ToString());
}


با اجرای کد بالا، متد FindAll شئ جدیدی از نوع <List

IEnumerable query = from p in persons
where p.Age < 20
select p;
foreach (Person person in query)
{
Console.WriteLine(person.ToString());
}


حال اگر بخواهیم شرط را تغییر بدهیم، بطوریکه علاوه بر سن افراد، نام آنها نیز مورد مقایسه قرار بگیرد کافیست کوئری خود را به صورت زیر تغییر دهیم:

IEnumerable query = from p in persons
where p.Age < 20 && p.FirstName.StartsWith("M")
select p;


تا اینجای مقاله در کوئری هایی که نوشتیم تنها از عملگر where برای فیل تر سازی اطلاعات استفاده کردیم، در LINQ عملگرهای دیگری برای مرتب سازی نتایج، گروه بندی، ادغام و ... وجود دارد که در بخش های بعدی این مقاله به تفصیل در مورد آنها صحبت خواهیم کرد.

اما یکی از قابلیت های جالب در نوشتن کوئری های LINQ که در محیط Visual Studio به چشم می آید قابلیت IntelliSense در نوشتن Query ها است که نوشتن آن ها را بسیار آسان می کند. همانگونه که شما وقتی شئ ای از نوع string ایجاد می کنید و می توانید به وسیله IntelliSense به تمامی متدهای آن دسترسی داشته باشید، در کوئری های LINQ نیز عملیات به همین گونه است. شما در هنگام نوشتن کوئری ها به تمامی متد هایی که برای یک شئ تعریف شده است دسترسی دارید مانند متد StartWith کلاس string که در کوئری های بالا از آن استفاده کردیم.

اما در بالا گفتیم که LINQ قابلیت کار با چندین منبع داده را دارد که در زیر به طور خلاصه به بررسی هر یک از این منابع می پردازیم:

1. LINQ to Object: قابلیت اجرای کوئری ها بر روی اشیاء موجود در حافظه را برای ما فراهم میکند. مانند کوئری بالا که بر روی لیست افراد <List
2. LINQ to XML: قابلیت اجرای کوئری ها بر روی مستندات XML را فراهم میکند. همچنین عملگرهایی را در اختیار شما قرار میدهد که به XPath وابسته بوده و به شما این امکان را می دهد در داخل مستندات XML حرکت کرده و گره های مختلف را مورد پیمایش قرار دهید. LINQ to XML از ویژگی های فضای نام System.Xml و System.Xml.Linq استفاده میکند. مخصوصا" Reader و Writer برای اجرای کوئری های. دو کلاسی که نقش مهمی را در LINQ to XML بازی می کنند، کلاس های XElement و XAttribute هستند. XElement نمایش دهنده المان های XML هستند و LINQ to XML از آنها برای ایجاد گره های مربوط به المان و فیل تر سازی اطلاعات استفاده می کند. هر XElement شامل یکسری صفات برای هر المان XML است که این صفات بوسیله کلاس XAttribute مشخص می شوند. مثال های زیر خلاصه ای از نحوه استفاده از امکانات LINQ to XML را نشان می دهد:

کاربرد کلاس XElement را در کد زیر مشاهده میکنید:

XElement x = new XElement(
"Person",
new XElement("FirstName", "Hosein"),
new XElement("LastName", "Ahmadi"));


حاصل قطعه کد بالا تگ های XML ایجاد شده زیر است:

Hosein
Ahmadi


حال اگر بخواهیم از XAttribute نیز در کلاس XElemet استفاده کنیم، کد بالا را به صورت زیر تغییر می دهیم:

XElement x = new XElement("Person",
new XAttribute("PersonID","10"),
new XElement("FirstName", "Hosein"),
new XElement("LastName", "Ahmadi"));


حال المان ایجاد شده توسط کد بالا به صورت زیر خواهد بود:

Hosein
Ahmadi


اما قدرت اصلی LINQ to XML در این قسمت معلوم می شود که میتوانیم پارامتر های ورودی جهت قرار گیری در المان XML تعریف شده را توسط یک Query انتخاب کنیم:

string[] names = { "Hosein", "Hamid", "Reza", "Mohammad", "Hadi" };

XElement x = new XElement("SelectedNames",
from n in names
where n.StartsWith("H")
select new XElement("Name", n));


المان ایجاد شده توسط کد بالا به صورت زیر است:

Hosein
Hamid
Hadi


در بخش های بعدی مقالات به طور مفصل در باره LINQ to XML صحبت خواهیم کرد.

3. LINQ to ADO.NET: این بخش در رابطه با اجرای کوئری های LINQ بر روی پایگاه های داده مانند SQL Server و همچنین دستکاری داده های آنان است. خود این بخش را می توان به سه بخش LINQ to SQL، LINQ to DataSet و LINQ to Entities تقسیم بندی کرد که هر کدام مبحث کاملی را می طلبند. به دلیل اینکه حجم مطالب مربوط به این بخش بسیار زیاد بوده و همچنین نیاز به آشنایی با مفاهیم پایه ای مانند ORM را دارد، توضیحات کامل در بخش مربوطه مطرح خواهند شد. تنها موردی که در اینجا می توان به آن اشاره کرد این است که در LINQ to SQL و LINQ to Entities برای موجودیت های بانک (جداول) در داخل برنامه اشیاء ای ایجاد می شوند که این اشیاء به واسطه یکسری Attribute ها توانایی تقابل با بانک و جداول مربوطه را دارند. کوئری های که برای خواندن اطلاعات از جدول به صورت کوئری های LINQ نوشته می شوند، به کوئری های SQL تبدیل شده و به سرویس SQL فرستاده می شوند تا نتایج مورد نظر گرفته شده و به کاربر نمایش داده شود. برای مثال کلاس زیر نمایش معادل یک جدول از بانک SQL است که در زبان #C بصورت یک کلاس تعریف شده است:

[Table(Name = "Person.Contact")]
public class Contact
{
[Column(DBType = "nvarchar(50) not null")]
public string FirstName;
[Column(DBType = "nvarchar(50) not null")]
public string LastName;
[Column(DBType = "nvarchar(50) not null")]
public string EmailAddress;
}


به استفاده از Attribute ها برای Map کردن جدول به صورت یک شئ توجه کنید. بوسیله LINQ to SQL می توان از روی این شئ بر روی جدول معادل در بانک اطلاعاتی کوئری هایی را اجرا کرد و یا رکورد هایی را دستکاری کرد.

مطالبی که تا اینجا بیان شد، خلاصه ای از توانایی ها و ویژگی های LINQ بود که در ادامه این مقاله با تفصیل در مورد هر یک از این ویژگی ها بحث خواهیم کرد. در بخش بعد در مورد ویژگی های جدید 3.0 #C که کاربرد های فراوانی در LINQ دارند بحث خواهیم کرد. این ویژگی ها به شرح زیر هستند:

  1. Implicity Typed Variables
  2. Anonymous Types
  3. Object Initialization
  4. Lamda Experssions **
  5. Automatic Implemented Properties
  6. Extension Methods


موفق باشید.

عنوان
1 آموزش LINQ در سی شارپ :: قسمت 1 - آشنایی با LINQ رایگان
2 آموزش LINQ در سی شارپ :: قسمت 2 - ویژگی های سی شارپ 3 رایگان
3 آموزش LINQ در سی شارپ :: قسمت 3 - ساختار کوئری های LINQ رایگان
4 آموزش LINQ در سی شارپ :: قسمت 4 - عملگرهای استاندارد (بخش اول) رایگان
5 آموزش LINQ در سی شارپ :: قسمت 5 - عملگرهای استاندارد (بخش دوم) رایگان
6 آموزش LINQ در سی شارپ :: قسمت 6 - عملگرهای استاندارد (بخش سوم) رایگان
7 آموزش LINQ در سی شارپ :: قسمت 7 - عملگرهای استاندارد (بخش چهارم) رایگان
زمان و قیمت کل 0″ 0
6 نظر
مهرناز معروف

با سلام و روز بخیر

ممنون از مطلب تون .. من یک سوال دارم ازتون چطوری می توانم در اینجا بهتون پیام بدم؟!

ایا می توانم ایمیلتونو داشته باشم؟

با تشکر

kashani.morteza

سلام آقای احمدی

خیلی زحمت کشیدی

خوب توضیح دادی و ما استفاده کردیم و ازت ممنونم

احمد جمالی

سلام مهندس جان

قسمت 8 تا 11 را کی میزارین رو سایت.

ممنون

NargesSadeghi

سلام قسمت 8 تا 11 رو روی سایت قرار نمیدین؟

سبحان مظفری

با سلام

من با linq به یک سوال برخوردم که هرچی سرچ میزنم موردی گیر نمیارم

من میخوام با استفاده از Index ستونام سلکت بزنم مثلا به جای اسم فیلدامون اندیس فیلدو بنویسم

با تشکر

حسین احمدی

سلام و عرض ادب، شما با skip و take می تونید این کار رو بکنید. برای مثال:

var customer = customers.OrderBy(c=>c.Id).Skip(20).Take(1);

کد بالا رکورد بیستم رو براتون بر میگردونه.

نظر شما
برای ارسال نظر باید وارد شوید.
از سرتاسر توسینسو
تنظیمات حریم خصوصی
تائید صرفنظر
×

تو می تونی بهترین نتیجه رو تضمینی با بهترین های ایران بدست بیاری ، پس مقایسه کن و بعد خرید کن : فقط توی جشنواره پاییزه می تونی امروز ارزونتر از فردا خرید کنی ....