با سلام خدمت تمامی دوستان.مطرح کردن این بحث با این تعداد کم استقبال واقعا جای تعجب دارد.از دوستان انتظار دارم که در این بحث با جدیت بیشتری ادامه دهنده و پیگیر مطالب باشند.
LINQ انقلابی در زمینه کدنویسی میباشد.این زبان هرچند ، بیشتر در رابطه با SQL قدرتمند است ، اما حقیقت امر آنست که LINQ در تمامی مراحل حل هر مساله ای که پردازشی روی داده های منظم انجام میگیرد دخیل است. Lambda Expression عنصری است که تحت عنوان متدهایی با فرمت خاص جدای از تعریف های ارائه شده برای متدهای متداول میباشند که دارای کاربردهای سریع و خاص در جهت استفاده بهینه از شکل انکپسوله شده LINQ هستند.
هرچند LINQ در زمینه کار با پایگاه داده ها بیشتر مورد توجه قرار میگیرد ، اما عناصر دیگر دات نت نظیرژنریک ها ، آرایه ها ، لیست ها و.... LINQ را در خود توسط Lambda Expression و Delegate ها انکپسوله کرده اند.از طرفی Delegate ها هم در جهت خدمت به زبان یکپارچه سازی داده ها توسعه داده شده است. تقریبا هر آنچه که در سی شارپ 2 نقطه قدرت بود و هر آنچه که زبانهای مبتنی بر پلت فرم دات نت را بر زبانهای دیگر برتری می داد به شکل مستقیم و یا غیر مستقیم در حال توسعه فقط بخاطر LINQ هستند.پس پس پس LINQ در آینده با قدرت بیشتری و با در اختیار گرفتن نحو سی شارپ و نهادینه کردن خود ، قدرت خودرا به نمایش میگذارد.
همانطور که دوستان عزیز هم میدانند پرس وجوهایی که توسط LINQ بدون تبدیل صریح از سوی برنامه نویس اخذ میشود دارای نوعی که مورد انتظار است نمیباشند
مثلا به کد زیر توجه کنید:
struct Student
{
int grade;
public int Grade
{
get { return grade; }
set { grade = value; }
}
string name;
public string Name
{
get { return name; }
set { name = value; }
}
string family;
public string Family
{
get { return family; }
set { family = value; }
}
}
static void Main(string[] args)
{
getStudents();
}
private static void getStudents()
{
Student[] allstudents = new Student[]
{
new Student(){ Name="Ali", Family="Amiri", Grade=19},
new Student() { Name="Sajjad", Family="Shirzadee", Grade=20},
new Student() { Name="Amir", Family="Hasani", Grade=18},
new Student() { Name="Amini", Family="Amini", Grade=13},
new Student() { Name="Reza", Family="Taheri", Grade=12},
new Student() { Name="Mohammad", Family="Shirazee", Grade=9},
};
var students = from d in allstudents
where d.Grade > 13
select new { d.Name, d.Family };
}
}
در این نمونه کد Structs ی به نام Student تعریف شده است که شامل فیلدهای نام، فامیلی و نمره می باشد .کاری که متد getStudents انجام میدهد آن است که دانش آموزانی را در آرایه ای ایجاد میکند و فیلدهای آنها را ست میکند. سپس پرس و جویی را برای گرفتن نام و فامیلی دانش آموزانی که نمره آنها بالاتر از 13 میباشد ایجاد میکنیم.حال اگر بخواهیم نمیتوانیم students را بازگشت بدهیم.چرا که نوع بازگشتی متدها را نمیتوان از نوع var تعریف کرد.اما در نسخه بعدی سی شارپ و وی بی این انتظار برآورده شده است و شما میتوانید نوع بازگشتی یک متد را حتی var تعریف کنید.این تغییر و تحولات نشان میدهند که مایکروسافت نگاه ویژه ای به LINQ دارد.
پس از این تعاریف (هر چند کم) که ارائه شد ، چیزی که بزرگترین مزیت LINQ است و به چشم هم نمی آید خیال راحت برنامه نویس در کار نکردن با کلمه Sql است.با این تفاسیر ، نگاه جدید توسعه دهندگان دات نت به مقوله پایگاه داده و وجود زیر ساخت مناسبی مانند LINQ زمینه تبدیل کار با پایگاه داده ها که از غیر شیء گراترین عناصر موجود در دات نت محسوب میشوند را به OR Mapping یا (نگاشت رابطه ای شیئ) تبدیل کرده است.در پس پرده توسط Entity Class میتوان با یک دیتابیس به مثابه آرایه ای از داده ها رفتار کرد.اینک LINQ با Entity Class ها ترکیب قدرتمندی تشکیل میدهند که میتوان از آنها برای اعتلای کدهای خود استفاده کرد.
یکی از نکاتی که بایستی به آن اشاره نمود این است که وقتی مثلا یک Entity Class را به دیتاگرید متصل میکنید مشکلی پیش نمی آید ، اما وقتی نتیجه پرس و جویی که یک نوع بدون نام است را به دیتا گرید متصل میکنید.مشکلی که پیش می آید این است که دیتا گرید آنقدر با هوش نیست که بتواند Property های موجود در آن نوع را تشخیص بدهد چرا که مکانیزم انجام این کار در دیتاگرید قرارداده نشده است.از آنجا که اشیایی که اینترفیس IList ویا IEnumerator ویا IBindingList را پیاده سازی میکنند ، میتوانند به دیتاگرید متصل شوند، پس حتی یک رشته را هم میتوان به دیتاگرید وصل کرد.اما داده ای نمایش داده نمیشود .
با این محدودیت خود ما باید جواب را هرچه بیشتر به IList ویا IBindingList نزدیک کنیم . یعنی به شکلی نوع بی نامی که حاصل از پرس وجو مییاشد را تبدیل کنیم .بنظر می آید برای رسیدن به این منظور باید از متد ()students.ToList استفاده کنیم.در اینصورت اگر یک دیتاگرید داشته باشیم
میتوانیم از این متد برای نسبت دادن داده ها به دیتاگرید استفاده کنیم.
نکته بعد :
واما Select های تودر تو به یک سری فرضیات احتیاج داریم خوب دقت کنید:
Grade:آرایه ای از اعداد اعشاری است که نمرات دانش آموز در آن ذخیره میشود.
و این کد مقداردهی اولیه تعدادی از دانش آموزان میباشد.
کد:
Student[] allstudents = new Student[]
{
new Student()
{
Name="Ali", Family="Amiri",
City="Kermanshah",Grade=new double[]{10,12,15,18,20}
},
new Student()
{
Name="Sajjad", Family="Shirzadee",
City="Tabriz",Grade=new double[]{9,6,14,13,20}
},
new Student()
{
Name="Amir", Family="Hasani",
City="Kermanshah", Grade=new double[]{20,17,9 ,16,19}
},
new Student()
{
Name="Amini", Family="Amini",
City="Mashhad", Grade=new double[]{5 ,10,11,12,20}
},
new Student()
{
Name="Reza", Family="Taheri",
City="Esfahan",Grade=new double[]{13,11,7 ,14,14}
},
new Student()
{
Name="Mohammad", Family="Shirazee",
City="Kerman", Grade=new double[]{10,12,15,18,20}
}
};
حالا اسم دانش آموزانی که اهل کرمانشاه هستند و معدل آنها بالای 15 میباشد را در دیتا گرید نمایش میدهیم :
کد:
var students = from d in
(from st in allstudents
where st.City == "Kermanshah"
select new { st.Name, Average = st.Grade.Sum() / st.Grade.Length })
where d.Average > 15
select new { d.Name };
this.dataGridView1.DataSource = students.ToList();
توضیح :
select درونی اسم ومعدل دانش آموزانی را در غالب نوع بدون نام به d نسبت میدهد و where
دوم نتایج را فیلتر میکند ودر قسمت آخر هم نام را از d برمیداریم
آخرین خط هم نتیجه را به لیست تبدیل و به دیتاگرید میدهیم.
منزه است دانای نیاموخته