سلام و سلامتی.
خوب، رسیدیده بودیم به متدهای کلاس DAL مون. قبلا هم گفتم که این کلاس برای ارتباط با پایگاه داده و خوندن ازش و اعمال تغییرات روشه. همونطور که توی پست های قبلی هم بررسی کرده بودیم، می تونیم هم از استورد پروسیجرها استفاده کنیم و هم می تونیم مستقیما دستورات اس کیو ال مونو اینجا بنویسیم. ما توی این برنامه از استورد پروسیجر استفاده می کنیم ،اینجوری خیلی بهتره چون اینجوری تمرین کردن برای پروژه های دیگه که نیاز به نوشتن کوئیری ها و پروسیجرها و توابع پیچیده تر دارین، مفیدتره،اینکه اونا توی پایگاه داده تون بمونن و تازه تستش هم راحتتر خواهد بود تا اینکه مستقیم توی کد نوشته بشن و همه چی قاطی شه.
قبل از اینکه شروع کنیم، توی پست قبلی راجع به استاتیک بودن یک عضو صحبت کردیم. اجازه بدین یه کم بیشتر راجع به اینکه اصلا این استاتیک چیه صحبت کنیم:
اعضای استاتیک (Static (Shared) Members):
اول از همه بگم که کلمه ی کلیدی Shared توی ویژوال بیسیک دات نت (Visual Basic.net) استفاده می شه و Static در سی شارپ دات نت (C#.net) .
وقتی فیلد، متد یا کلاسی رو حتی، استاتیک تعریف می کنیم همیشه از این عضو یکی و همه جا یکسان ازش داریم. چرا؟ چون الان براتون با مثال نشون می دم که عضوهای استاتیک بدون ایجاد شی یا نمونه (object ,instance) - یا بهش وهله هم گفته می شه – استفاده می شن و مستقیما به اسم کلاس می چسبن نه به وهله یا شی. به همین دلیل بعد از تعریف یک فیلد استاتیک شما می تونین بدون ایجاد شی، بهش مقدار بدین.
فرضا اینو داریم: یک فیلد که استاتیک تعریف شده:
Public class Test
}
;public static int MyField
{
حالا شما نیاز ندارین شی ای از این کلاس Test بسازین (newکنین) بعد از این فیلد استفاده کنین. همونجا می تونین بهش مقدار اولیه هم بدین. مثلا:
;Public static int MyField = 20
توی برنامه مون فقط کافیه هر جا بهش احتیاج داشتین از Test.MyField (نام فیلد استاتیک . نام کلاس) استفاده کنین که مقدارش هم همیشه مشخص و یکسانه.
اما حالا اگه این MyField استاتیک نبود چی؟ اونوقت شما باید شی نیو می کردین بعد ازش استفاده می کردین.اینجوری:
;()Test Object1 = new Test
;()Test Object2 = new Test
;Object1.MyField = 10
;Object2.MyField = 30
خوب چی شد؟! الان این شد 2تا فیلد متفاوت با مقدارهای متفاوت. (دینگ دینگ: Object1 بعنوان مثال، یک Instance از کلاس Test است.)
پس از اعضای استاتیک، فقط یه نمونه داریم صرف نظر از اینکه چه تعداد نمونه(Instance) از نوعشون (Type)ساخته شده.
نمی شه اعضای استاتیک رو با Instance صدا کرد یعنی اگر توی مثال بالا MyField استاتیک باشه نمی شه نوشت ;Object1.MyField = 10 .
در مورد متد ها هم همینه، یعنی به Type وابسته هستن نه نمونه ای(instance) از نوع (Type). مثلا شما یه سری متد مهم دارین. اینا رو Static تعریف میکنین و می ذارین توی یه کلاس. بعد هر جا خواستین ازشون استفاده کنین دیگه لازم نیست اول از کلاس یه شی بسازین و بعد از متد استفاده کنین.مستقیم از اسم کلاس و متد استفاده می کنیم.دقیقا مثل کاری که توی دفترچه تلفن کردیم. اگه دقت کنین می بینین متدهای کلاس ِ DALمون رو public static تعریف کردیم و توی لایه ی نمایش برای فراخوانیش از اسم کلاس . اسم متد استفاده کردیم.
نکته:
1.اعضای استاتیک (static members)، می تونن public یا private باشن.
2. از یک عضو استاتیک نمی شه به یک عضو غیر استاتیک (داینامیک) دسترسی داشت. اما
از یک عضو داینامیک می شه به یک عضو استاتیک دسترسی داشت.
حالا چرا اینجوریه؟ برای این نمی شه از عضو استاتیک به عضو داینامیک دسترسی داشت چون عضو استاتیک خارج از وهله کار می کنه و معنی نمی ده که بخواییم به فیلد داینامیک دسترسی پیدا کنیم چون این فیلد بعد از تعریف وهله (new کردن یه شی از کلاس) معنی پیدا می کنه نه توی نام کلاس. مثلا:
}public class MyClass
;public static int A
;public int B
} ()public static int Add
??!!! return (MyClass.A + B); // error, B
{
{
---------------------------------
و اما می ریم سراغ متدهای کلاس DAL . درکلاس DAL معمولا یک سری متدهایی داریم که با دیتا بیس در ارتباط هستن. در نتیجه هر متدی که توی DAL داریم معادلش یه استورد پروسیجر (Stored procedure) هم توی دیتا بیس داریم. برای برنامه هایی مشابه دفترچه ی تلفن اصطلاحی داریم با نام CRUD (Create ,Retrieve ,Update ,Delete)،که توابعی هستند که هم توی کلاس DAL ازشون استفاده می شه هم استورد پروسیجرهاش رو داریم.
متد () GetEntries:
- این متد قراره چی کار کنه؟
همونطور که از اسمش مشخصه قراره یه سری داده هامون رو از پایگاه داده بخونه. برای اینکه داده های پایگاه داده رو به کاربر نشون بدیم احتیاج به این متد داریم تا به پایگاه داده وصل بشه و این کارو برامون انجام بده با استفاده از استورد پروسیجر ِ Select . مثلا نام و نام خانوادگی و شماره تلفن و ... که قبلا کاربر ثبت کرده و حالا می خواد ببینتشون.
- این متد چه جوری کار می کنه؟
1-2 . اول باید یک شی از کلاس SqlConnection ایجاد کنیم و با ConnectionString آدرس دهیش کنیم .(به پست قبل مراجعه کنین.). این کار یه کانال به پایگاه داده برامون باز می کنه.
2-2. حالا یک شی از کلاس SqlCommand ایجاد می کنیم. همونطور که از اسمش مشخصه کامندها برای دستوراتی که قراره به پایگاه داده فرستاده بشن استفاده می شه.
3-2. حالا کانکشنمون رو باز می کنیم. یعنی چی؟! خوب کانالمون رو به پایگاه داده باز می کنیم دیگه. این کارو ابتدای ارتباط و دادن دستورات به دیتابیس انجام می دیم و در آخر کار هم می بندیمش. می دونین که امنیت و اینا...
4-2. حالا باید پارامترهای کامندمون رو مشخص کنیم. اول کانکشن رو بهش می دیم یعنی می گیم از کجا دستورات رو بفرسته. بعدش نوع دستور رو که قرار استفاده از استورد پروسیجر باشه بهش می گیم و در انتها هم اسم ِ استورد پروسیجرمون رو می دیم.
** اینجا یک ;cmd.Parameters.Clear // داریم. (این دوتا اسلش رو گذاشتم تا این خط جز اجرای برنامه نباشه، چون اینجا بودن یا نبودش فرقی نداره.) این دستور پارامترهایی که قبلا به کامند اضافه شده باشن رو حذف می کنه تا مشکلی توی اجرای کامندی که ما می خواییم پیش نیاد.اما توی این برنامه چون ما در هر قسمت،در هر متد از اول ایجادش می کنیم (New) نیازی نیست.
5-2. همونطور که در تعریف متد می بینین، متد ما یک خروجی از جنس دیتاتیبل داره(پشت متد نوع خروجی ای که به ما می ده رو می نویسیم و جلوش توی پرانتز ورودیای که می گیره همراه با جنسش- جلوتر می بینین!). یک جدول که داده ها رو توش می ریزه و به ما برمیگردونه. پس باید یه شی از جنس دیتاتیبل ایجاد کنیم و داده ها رو توش بریزیم که اینجا اسمش رو گذاشتیم dt .
6-2. حالا چه جوری داده های Select شده رو می خونه؟ و همین جا بگم وقتی داره چیزی رو می خونه باید یه جایی هم داده های خونده شده رو بریزه درسته؟ خوب کامند یک دستور داره برای این کار به اسم ()ExecuteReader . خوب وقتی این دستور داده ها رو خوند اونا رو می ریزیم توی شی ای از جنس SqlDataReader به نام مثلا dr .
7-2. و سرانجام جدول dtمون رو با داده های dr لود می کنیم و returnهم که جدول رو برمی گردونه.
8-2. در آخر کار هم کانکشن رو می بندیم. این باید همیشه یادتون بمونه که هر بار که کانکشنی رو باز می کنین باید حتما ببندیدش.
سوال:
1. این{}try و {}finally برای چی هستن؟
جواب: در برنامه نویسی مبحی داریم بانام Exception Handling. که در واقع برنامه ریزی و رفع Errorهایی که در زمان اجرای برنامه ممکنه پیش بیان که بهش می گن (Run - Time Error)،اینا error هایی هستند که بعد از Test و Debug برنامه ممکنه پیش بیان، بعد از اینکه مثلا errorهای مربوط به Syntax ِ برنامه رو رفع کردیم.
برای اداره کردن Exception ها از سینتکسی با نام Try…Catch…Finally… استفاده می کنیم.
Try
{
کدهای معمولی برنامه مون رو اینجا توی بلوک try می نویسیم.
}
Catch
{
کدهایی که باید در صورت مواجه شدن با خطاهای زمان اجرا(run-time errors)، اجرا بشن تا خطا را اداره (Handle) کنند اینجا قرار می گیرند.
}
بعد از بلوک try می تونه یک یا چندین Catch وجود داشته باشد که هر کدوم یه Exception رو برطرف کنه...
.
.
Finally
{
کدهایی رو که می خواییم در هر صورت اجرا بشن، حتی مثلا وقتایی که اگر خواستیم error رو برگردونیم،به اصطلاح پرتاب کنیم ، یعنی به کاربر پیغام بدیم (Throw)، یا حتی اگر توی کدها Return داشتیم و از برنامه خارج شدیم،باز اجرا بشن از این بلوک استفاده می کنیم.که قبل از خارج شدن از برنامه کدهای اینجا اجرا بشن.
}
2. دستورهای کامند(Command) چند دسته هستن؟
جواب: و اما دستورات کامند 3 جورن:
1. دستوراتی که جوابی ندارن و چیزی برنمی گردونن، مثلا بهش می گین برو فلان دیتا رو از فلان تیبل پاک کن، یا فلان داده رو اضافه کن. اسم این دستور هست: ()ExecuteNonQuery .
یه مثال توی SQL برای این دستور :
Delete From Table_pb
Where id=@id
2. دستوراتی هستن که جوابشون یک عددِ. مثلا می خوایید بدونین چندتا شماره ی تلفن توی دفترچه تلفنتون دارین.اسم این دستورم هست : ()ExecuteScaler .
Select Count * From Table_pb
3. و نوع سوم همونطور که استفاده کردیم، یک مجموعه دیتا برمی گردونه. ()ExecuteReader .
Select * From Table_pb
متد Insert :
- قراره این متد چی کار کنه؟
اولین چیزی که از دفترچه تلفنمون انتظار داریم اینه که بتونیم یه سری نام و شماره و آدرس و ... رو توش ذخیره کنیم.خوب برای این کار به متدی احتیاج داریم که اطلاعات رو از کاربر بگیره (توسط تکست باکس ها) و بعد اونا رو به پایگاه داده مون اضافه کنه.
نکات:
1-1. همونطور که مشخصه این متد قرار نیست خروجی داشته باشه پس void تعریف می شه که پشت متد نوشته می شه و به این معنیه که متد ما خروجی نخواهد داشت.
2-1. دلیل پابلیک بودن و استاتیک بودن رو هم که توی پست قبلی بررسی کردیم.
3-1. خوب رسیدیم به اولین جایی که از کلاس BLL استفاده می کنیم. قرار شد یه سری ورودی از کاربر بگیریم و به این متد بدیم و همونطور که قبلا هم گفتم لایه ی BLL رابط بین کاربر و لایه ی DAL ِ که به دیتابیس متصله. پس یه شی از جنس کلاس BLL تعریف می کنیم که این می شه وردیه متد Insert .
- متد Insert چطوری کار می کنه؟
1-2. قسمت اولش که باز کردن یه کانال و مقدار دهی پارامترهای کامنده مثل متد قبلیه...
2-2. خوب اینجا یه سری دستور مشابه پشت هم داریم که پارامترهایی رو که می خواهیم برای اجرا به دستورمون بدیم تا اضافه کنه به دیتا بیس اینجا به کامند می دیم. برای فراخونی پارامترها لازمه که نوع داده شون رو هم مشخص کنیم، که همه از همون نوعی هستند که توی جدول دیتابیس و همینطور ورودی استورد پروسیجرها تعیین کردیم. (SqlDBType یک نوع داده توی پایگاه داده ست،تقریبا مشابه ی انواع داده در برنامه نویسی.)
3-2. و بعد از این پارامترها توسط ورودیهایی که کاربر توی تکست باکس ها وارد می کنه و کلاس BLL برامون می فرسته، مقداردهی می شن و با دستور ExecuteNonQuery که جلوتر گفتم داده ها به دیتا بیس اضافه می شن.
سوال:
1. چرا برای 3تا از ورودیهامون شرط گذاشتیم؟ و شرط چی رو بررسی می کنه؟
جواب: چیزی که برامون توی دفترچه تلفن مهمه اینه که لااقل مشخصات اصلی و یه شماره ذخیره بشه، پس لازمه یه شرط بذاریم که کاربر حتما نام و نام خانوادگی و اولین شماره رو وارد کنه، حالا بقیه اطلاعات می تونه اختیاری باشه.
و اما شرط ما هم ،همین کارم می کنه ، یعنی اگر اطلاعات پر شده باشه و خالی نباشه (علامت ! یعنی نامساوی) ، مقدار تکست باکس و بده به پارامتری که قراره با کامند واسه اجرا بره به دیتابیس .
2. String پشت ِ ()IsNullOrEmpty واسه چیه؟
جواب: IsNullOrEmpty یک متد استاتیک از کلاس ِ String است بنابر داستان مفصل Static ها، اسم متد استاتیک با اسم کلاس می آد. ;()String.IsNullOrEmpty
خوب، می مونن متدهای Delete و Update و Retrieve.
متد (Update)با متد (Insert) فرق چندانی نداره جز اینکه یک آی دی (Id) هم می گیره که این id در واقع شماره ی سطریه که کاربر می خواد ویرایشش کنه. که بعدا توی لایه ی نمایش می بینین که از این id چه جوری استفاده می شه.
متد (Delete) هم مشابه متد(Insert) هست با این تفاوت که فقط مقدار (Value) ِ آی دی (id) تنظیم می شه. که در واقع با این کار id سطری رو که می خواییم از جدولمون توی پایگاه داده پاک بشه به دیتا بیس ارسال می کنیم. توی لایه ی نمایش می بینین که این id با انتخاب و کلیک کاربر روی سطر مورد نظرش مشخص می شه.
فقط متد (Retrieve) از این کلاس DAL می مونه برای پست بعدی.
// اگر تا اینجا سوالی براتون پیش اومده ، تبسم خوشحال می شه بتونه کمک کنه.
