PDA

View Full Version : تبدیل تمام جدولهای یک بانک به اشیاء



Sajjad1364
جمعه 09 اسفند 1387, 01:04 صبح
تمامی کسانی که به نحوی با بانک اطلاعاتی و اشیاء Command سروکار دارند حتما حس کردن که کار کردن با فیلدها و دستیابی به رکوردها چقدر خسته کنندس.
اینکه همیشه در دستیابی به هر ستون باید از رشته ها استفاده کنین واقعا حالگیره
و احتمال اشتباه همیشه وجود داره.
چونکه این تالار رو (مباحث مربوط به دسترسی به داده ها از طریق ADO.Net و LINQ )
نامگذاری کردن اما هنوز ظاهرن کاربرها بیشتر دوست دارن با ADO.Net کار کنن و نه چیز دیگه ای. اما اگر طعم کار با LINQ رو بچشن گمان نکنم کسی سراغ درج کردن اطلاعات(مگر در موارد خاص) بوسیله مثلا SqlCommand بره.
از اونجاییکه فعلا تمایلی به استفاده از LINQ به چشم نمیخوره میخام که کمی از قدرتش رو و مهمتر از همه راحتی استفاده از اونو اینجا نشون بدم
فرض کنین بانکی بنام School داریم و جدولی در این بانک با نام Student وجود داشته باشه
روش معمولی که برای دستیابی به داده ها توسط بیشتر کاربرا مورد استفاده قرار میگیره اینه که برای دستیابی به هر رکورد یه کوئری میگیرن و اگر بدون دیتاست بخوان با داده ها کارکنن واقعا طاقت فرساس.
اما اگر باروش زیر داده ها بازیابی بشن کارها خیلی آسون میشه:
فرض کنین جدول Student فیلدهایی تحت عنوان : Family ,Name, Address,ID داشته باشه
کلاسی رو با خصوصیاتی همنام با ستونهای جدول ایجاد میکنیم :


public class Student
{
private String _Name;
public String Name
{
get { return _Name; }
set { _Name = value; }
}
private String _Family;
public String Family
{
get { return _Family; }
set { _Family = value; }
}
private String _Address;
public String Address
{
get { return _Address; }
set { _Address = value; }
}
private long _ID;
public long ID
{
get { return _ID; }
set { _ID = value; }
}
}


حالا کد زیر رو برای ارتباط با دیتابیس و استخراج تمام رکوردهای فقط جدول Student مینویسیم :


String connection = "Data Source=.\\SQLEXPRESS;Initial Catalog=School;Integrated Security=True";
SqlConnection con = new SqlConnection(connection);
SqlCommand command = new SqlCommand("SELECT * FROM Students", con);
command.Connection.Open();
DbDataReader reader = command.ExecuteReader();


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



DataContext d = newDataContext(connection);
IEnumerable<Student> stu = d.Translate<Student>(reader);


از شئ DataContext برای ارتباط و از متد Translate برای تبدبل داده ها به مدل شئ
حالا یه Collection دارین (stu) که براحتی میتونین هر کاری رو انجام بدید.

نکته: باید توجه داشت باشین اگر نام Property ها با نام ستونها همخوانی نداشته باشه براحتی از عملیات انتساب مقادیر به Propertyها بدون تولید خطایی صرفنظر میشه (مثلا اگر بجای Name نوشته بودیم Nam) .

اگر بخایم مثلا 1000 رکورد رو توی یک دیتاست لود کنیم عملا برنامه مون رو به چالش کشیدیم و فضایی که اشغال میشه بصورت فزاینده ای افزایش پیدا میکنه اما اگر از این تکنیک کمک بگیریم فواید زیر رو بدست میاریم.
1- اشغال کردن فضای خیلی کمی از رم (چندین برابر کمتر از دیتاست و سریعتر).
2- در کار با داده ها دیگر امکان اشتباه های دست و پا گیر از سوی کاربر در نتیجه کار با دستورات SQL وجود ندارد.
3- سرعت خیلی بالا در کار با داده ها
4- استفاده از داده های کاملا زنده بدون استفاده از عملیات های مکرر استخراج داده.
5- بهره گیری از نهایت قدرت LINQ در کار با داده ها .
6- بهره مندی از تمام امکانات زبان بکارگرفته شده در توسعه کار با داده ها (استفاده از ژنریک ها ، انواع بدون نام ، وراثت و .....).

نکته : مادامیکه عملیاتی رو انجام ندادین که باعث بشه کالکشن stu پیمایش بشه عملیات تبدیل صریح صورت نمیگیره.یعنی اگر تعداد رکوردهابرابر 1000 عدد باشه بعد از اجرای متد Translate ، صریحا 1000 شئ از نوع Student ساخته نمیشه .با این ترفند اگر اجرای متد Translate مثلا در رویداد Load فرم انجام بشه دیگه تا وقتیکه متد اجرا میشه نمایش فرم به تاخیر نمی افته.در صورتیکه stu به لیست و یا آرایه تبدبل بشه آنوقت 1000 بار از شئ Student نمونه سازی خواهد شد.

با توجه به این تکنیک دیگه با قوانین خشک ودست و پا گیر کوئری و کوئری گرفتن سروکار ندارین اگر مثلا از استفاده از کد زیر(دانش آموزانی که نام خانوادگیشون با حرف A شروع بشه) به هر دلیلی خوشتون نمیاد یا سخته :


IEnumerable<Student> st = a.Where(s => s.Family.StartsWith("A"));


بجای اینکه بیاین کوئری بگیرین حداقل یه foreach ساده بذارین و بگردین و نتایج رو در غالب اشیاء Student ذخیره کنین تا با اجرای هر کوئری مکررا سمت سرور نرین.

در پایان باید گفت که متاسفانه هنوز اونطور که باید و شاید از LINQ مثلا در مقابل WPF استقبال نشده و استفاده از Command هنوز خیلی متداوله.:متفکر::متعجب:

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