با سلام به شما دوستای عزیز ،امروز با مبحث دستورالعمل نوشتن query ها در LINQ در خدمت شما هستم .این دستورالعمل ویژگی های زبان C# را توضیح می دهد که برای نوشتن عبارات LINQ query استفاده می شوند. پس از تکمیل این دستورالعمل شما آماده ی حرکت بر روی نمونه ها و مستندات مربوط به ارائه دهنده ی خاص LINQ مورد علاقه ی خود، خواهید بود، مانند LINQ به SQL، LINQ به DataSets یا LINQ به XML.
پیش شرایط:
این دستورالعمل ویژگی هایی را ملزم می کند که در Visual Studio 2008 معرفی شده اند.
برای یک ورژن ویدئویی از این بخش Video How to: Writing Queries in C# (LINQ) را بررسی کنید.
ایجاد یک پروژه ی C#
برای ایجاد یک پروژه:
۱٫ Visual Studio را آغاز کنید.
۲٫ در نوار منو File, New, Project را انتخاب کنید.
دیالوگ باکس New Project باز می شود.
۳٫ Installed را باز کنید، Templates را باز کنید، Visual C# را باز کنید و سپس Console Application را انتخاب کنید.
۴٫ در تکست باکس Name، یک نام متفاوت وارد کنید و یا نام پیش فرض را بپذیرید و سپس دکمه ی OK را انتخاب کنید. پروژه ی جدید در Solution Explorer ظاهر می شود.
۵٫ دقت داشته باشید که پروژه ی شما دارای یک مرجع به System.Core.dll و یک مسیر using برای فضانام System.Linq می باشد.
ایجاد یک منبع داده ی in-Memory:
منبع داده برای query ها یک لیست از آبجکت های Student (دانشجو) می باشد. هر رکورد از دانشجو دارای یک نام، نام خانوادگی و یک ردیف از اعداد صحیح می باشد که نمره ی امتحان آنها را در کلاس نشان می دهد. این کد را در پروژه ی خود کپی کنید. به ویژگی های زیر دقت داشته باشید:
· گروه Student حاوی پراپرتی های اجراشونده ی خودکار می باشد.
· هر دانشجو در لیست با یک آبجکت اولیه آغاز می شود.
· خود لیست با یک مجموعه ی اولیه آغاز می شود.
این ساختار کلی داده آغاز خواهد شد و بدون فراخوانی مشخص روی هر سازنده یا عضو مشخص در دسترس می باشد.
افزودن منبع داده:
· گروه Student و لیست اولیه ی دانش آموزان را به گروه Program در پروژه ی خود ا اضافه کنید.
public class Student
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
public List Scores;
}
// Create a data source by using a collection initializer.
static List students = new List
{
new Student {First=”Svetlana”, Last=”Omelchenko”, ID=111, Scores= new List {97, 92, 81, 60}},
new Student {First=”Claire”, Last=”O’Donnell”, ID=112, Scores= new List {75, 84, 91, 39}},
new Student {First=”Sven”, Last=”Mortensen”, ID=113, Scores= new List {88, 94, 65, 91}},
new Student {First=”Cesar”, Last=”Garcia”, ID=114, Scores= new List {97, 89, 85, 82}},
new Student {First=”Debra”, Last=”Garcia”, ID=115, Scores= new List {35, 72, 91, 70}},
new Student {First=”Fadi”, Last=”Fakhouri”, ID=116, Scores= new List {99, 86, 90, 94}},
new Student {First=”Hanying”, Last=”Feng”, ID=117, Scores= new List {93, 92, 80, 87}},
new Student {First=”Hugo”, Last=”Garcia”, ID=118, Scores= new List {92, 90, 83, 78}},
new Student {First=”Lance”, Last=”Tucker”, ID=119, Scores= new List {68, 79, 88, 92}},
new Student {First=”Terry”, Last=”Adams”, ID=120, Scores= new List {99, 82, 81, 79}},
new Student {First=”Eugene”, Last=”Zabokritski”, ID=121, Scores= new List {96, 85, 91, 60}},
new Student {First=”Michael”, Last=”Tucker”, ID=122, Scores= new List {94, 92, 91, 91} }
};
افزودن یک دانشجو به لیست دانشجویان:
· یک Student جدید به لیست Students اضافه کنید و از یک نام و نمرات امتحان مورد انتخاب خود استفاده کنید. سعی کنید اطلاعات مربوط به دانشجوی جدید را تایپ کنید تا ترکیب مربوط به آبجکت آغازگر را بهتر یاد بگیرید.
ایجاد query
برای ایجاد یک query ساده:
در متود اصلی برنامه یک query ساده ایجاد کنید که هنگامی که اجرا می شود، لیستی از همه ی دانشجویانی را ارائه دهد که نمره ی آنها در اولین تست بیشتر از ۹۰ باشد. دقت داشته باشید که چون کل آبجکت Student انتخاب شده است، نوع query در واقع IEnumerable می باشد. گرچه کد می تواند از تایپ ضمنی هم با استفاده از لغت کلیدی var استفاده کند، تایپ واضح برای توضیح نتایج استفاده می شود.
دقت داشته باشید که متغیر محدوده، و دانشجو مربوط به query به عنوان یک مرجع برای هر Student در منبع در نظر گرفته می شوند که دسترسی اعضا را برای هر آبجکت تامین می کنند.
// Create the query.
// The first line could also be written as “var studentQuery =”
IEnumerable studentQuery =
from student in students
where student.Scores[0] > 90
select student;
اجرای Query
برای اجرای query:
۱٫ اکنون لوپ foreach را که باعث اجرای query خواهد شد، ینویسید. به موارد زیر در مورد کد دقت داشته باشید:
· هر عنصر در توالی گزارش شده از طریق تکرار متغیر در لوپ foreach در دسترس می باشد.
· نوع این متغیر Student می باشد و نوع متغیر query سازگار می باشد، IEnumerable.
۲٫ پس از اینکه این کد را اضافه کردید، با فشار دادن Ctrl + F5 برنامه را ساخته و اجرا کنید تا نتایج را در پنجره ی Console مشاهده کنید.
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
Console.WriteLine(“{0}, {1}”, student.Last, student.First);
}
// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
۳٫ افزودن یک فیلتر شرطی دیگر:
· می توانید شرایط چندگانه ی Boolean را در عبارت where ترکیب کنید تا یک query را بیشتر بهبود بخشید. کد زیر یک شرط اضافه می کند، طوریکه query دانشجویانی را گزارش می دهد که اولین نمره ی آنها بیشتر از ۹۰ و آخرین نمره ی آنها کمتر از ۸۰ باشد. عبارت where باید مشابه کد زیر باشد.
where student.Scores[0] > 90 && student.Scores[3]
var studentQuery2 =
from student in students
group student by student.Last[0];
۲٫ دقت داشته باشید که اکنون نوع query تغییر یافته است. اکنون این query یک توالی از گروه هایی را تولید می کند که دارای نوع char به عنوان کلید و ترتیبی از آبجکت های Student می باشد. از آنجاییکه نوع query تغییریافته است، کد زیر اجرای لوپ foreach را نیز تغییر می دهد:
// studentGroup is a IGrouping
foreach (var studentGroup in studentQuery2)
{
Console.WriteLine(studentGroup.Key);
foreach (Student student in studentGroup)
{
Console.WriteLine(” {0}, {1}”,
student.Last, student.First);
}
}
// Output:
// O
// Omelchenko, Svetlana
// O’Donnell, Claire
// M
// Mortensen, Sven
// G
// Garcia, Cesar
// Garcia, Debra
// Garcia, Hugo
// F
// Fakhouri, Fadi
// Feng, Hanying
// T
// Tucker, Lance
// Tucker, Michael
// A
// Adams, Terry
// Z
// Zabokritski, Eugene
۱٫ برای اجرای برنامه Ctrl + F5 را فشار دهید و نتایج را در پنجره ی Console مشاهده کنید.
برای تایپ کردن متغیرها به طور ضمنی:
· کد گذاری آشکار IEnumerables از IGroupings می تواند خیلی سریع خسته کننده شود. شما می توانید همان query و لوپ foreach را با استفاده از var خیلی سازگارتر سازید. لغت کلیدی var انواع آبجکت های شما را تغییر نمی دهد، بلکه فقط کامپایلر را می سازد تا به این انواع اشاره کند. نوع studentQuery و تکرار متغیر group را به var تغییر دهید و query راگزارش دهید. دقت داشته باشید که در لوپ داخلی تر foreach، تکرار هنوز با عنوان Student تایپ می شود و query درست مانند قبل کار می کند. تکرار متغیر s را به var تغییر دهید و مجددا query را اجرا کنید. مشاهده می کنید که دقیقا همان نتایج را دریافت می کنید.
var studentQuery3 =
from student in students
group student by student.Last[0];
foreach (var groupOfStudents in studentQuery3)
{
Console.WriteLine(groupOfStudents.Key);
foreach (var student in groupOfStudents)
{
Console.WriteLine(” {0}, {1}”,
student.Last, student.First);
}
}
// Output:
// O
// Omelchenko, Svetlana
// O’Donnell, Claire
// M
// Mortensen, Sven
// G
// Garcia, Cesar
// Garcia, Debra
// Garcia, Hugo
// F
// Fakhouri, Fadi
// Feng, Hanying
// T
// Tucker, Lance
// Tucker, Michael
// A
// Adams, Terry
// Z
// Zabokritski, Eugene
مرتب سازی گروه ها با مقادیر کلیدی آنها:
· وقتی query قبل را اجرا می کنید، دقت داشته باشید که گروه ها به ترتیب حروف الفبا نیستند. برای تغییر این مسئله باید یک عبارت orderby بعد از عبارت group ارائه دهید. اما برای استفاده از یک عبارت orderby، ابتدا به یک شناسنده نیاز دارید که برای گروه های ایجاد شده توسط عبارت group به عنوان یک مرجع عمل می کند. می توانید با استفاده از لغت کلیدی into، یک شناسنده ارائه دهید، مانند زیر:
var studentQuery4 =
from student in students
group student by student.Last[0] into studentGroup
orderby studentGroup.Key
select studentGroup;
foreach (var groupOfStudents in studentQuery4)
{
Console.WriteLine(groupOfStudents.Key);
foreach (var student in groupOfStudents)
{
Console.WriteLine(” {0}, {1}”,
student.Last, student.First);
}
}
// Output:
//A
// Adams, Terry
//F
// Fakhouri, Fadi
// Feng, Hanying
//G
// Garcia, Cesar
// Garcia, Debra
// Garcia, Hugo
//M
// Mortensen, Sven
//O
// Omelchenko, Svetlana
// O’Donnell, Claire
//T
// Tucker, Lance
// Tucker, Michael
//Z
// Zabokritski, Eugene
وقتی که این query را اجرا می کنید، مشاهده خواهید کرد که گروه ها به ترتیب حروف الفبا مرتب شده اند.
معرفی یک شناسنده با استفاده از let:
· می توانید از لغت کلیدی let برای معرفی یک شناسنده برای هر نتیجه ی عبارت در عبارت query استفاده کنید. این شناسنده می تواند مناسب باشد، مانند مثال زیر، یا می تواند با مرتب کردن نتایج یک عبارت اجرا را برقرار کند، بنابراین لازم نیست چند بار محاسبه شود.
// studentQuery5 is an IEnumerable
// This query returns those students whose
// first test score was higher than their
// average score.
var studentQuery5 =
from student in students
let totalScore = student.Scores[0] + student.Scores[1] +
student.Scores[2] + student.Scores[3]
where totalScore / 4 < student.Scores[0]
select student.Last + " " + student.First;
foreach (string s in studentQuery5)
{
Console.WriteLine(s);
}
// Output:
// Omelchenko Svetlana
// O'Donnell Claire
// Mortensen Sven
// Garcia Cesar
// Fakhouri Fadi
// Feng Hanying
// Garcia Hugo
// Adams Terry
// Zabokritski Eugene
// Tucker Michael
استفاده از method syntax در یک عبارت query:
· همانطور که در Query Syntax and Method Syntax in LINQ (C#) توضیح داده شد، برخی عملکردهای query تنها با استفاده از method syntax توضیح داده می شوند. کد زیر نمره ی کلی هر Student را در توالی نمره محاسبه می کند و سپس روش Average() را روی نتایج query فرا می خواند تا نمره ی میانگین کلاس را محاسبه کند. به قرارگیری پرانتزها در اطراف عبارت query دقت داشته باشید.
var studentQuery6 =
from student in students
let totalScore = student.Scores[0] + student.Scores[1] +
student.Scores[2] + student.Scores[3]
select totalScore;
double averageScore = studentQuery6.Average();
Console.WriteLine("Class average score = {0}", averageScore);
// Output:
// Class average score = 334.166666666667
تبدیل یا طرح در عبارت select:
۱٫ برای یک query خیلی متداول است تا یک توالی ایجاد کند که عناصر آن با عناصر در ترتیب های منبع متفاوت است. Query قبلی و اجرای لوپ را حذف کنید یا در مورد آن کامنت بدهید و آن را با کد زیر جایگزین کنید. دقت داشته باشد که query ترتیبی از رشته ها را ( نه دانشجویان) گزارش می دهد و این واقعیت در لوپ foreach منعکس می شود.
IEnumerable studentQuery7 =
from student in students
where student.Last == “Garcia”
select student.First;
Console.WriteLine(“The Garcias in the class are:”);
foreach (string s in studentQuery7)
{
Console.WriteLine(s);
}
// Output:
// The Garcias in the class are:
// Cesar
// Debra
// Hugo
۲٫ کد پیشین در این دستورالعمل نشان داد که میانگین نمره ی این کلاس ۳۳۴ می باشد. برای تولید ترتیبی از Students که نمره ی کلی آنها بیشتر از میانگین کلاس می باشد، به همراه Student ID آنها، می توانید از یک نوع بدون نام در عبارت select استفاده کنید.
var studentQuery8 =
from student in students
let x = student.Scores[0] + student.Scores[1] +
student.Scores[2] + student.Scores[3]
where x > averageScore
select new { id = student.ID, score = x };
foreach (var item in studentQuery8)
{
Console.WriteLine(“Student ID: {0}, Score: {1}”, item.id, item.score);
}