PDA

View Full Version : آموزش: پیاده سازی معماری چند لایه با استفاده از لینک(قسمت اول)



reza344
شنبه 07 اسفند 1389, 18:20 عصر
Multi tier architecture for Linq to Sql هدف این مقاله نمایش چگونگی پیاده سازی معماری چند لایه با استفاده از ابزار لینک و همچنین استفاده از ObjectDataSource بعنوان منبع داده ها در برنامه میباشد . ویژگیهای کلیدی این روش توجه به خواسته های موجود از datacontext و کلاس های موجود مخزن است که ارائه دهنده راه کارهای ساده پیاده سازی عملیات اضافه کردن ، ویرایش کردن و حذف کردن داده ها (CRUD) با استفاده از Generic DataType ها میباشد . اگر نیاز به اطلاعات بیشتر در مورد نوع داده ای Generic هستید از این مقاله (http://arjmandi.com/file.axd?file=2009%2f11%2fgeneric.pdf) استفاده کنید . در اصل در این مقاله ما قصد ایجاد لایه Data Access یا همان DAL را با استفاده از تکنولوژی Linq داریم .
Generic Entity Repository هر موجودیت بانک اطلاعاتی دارای یک کلاس مرتبط مخزن داده ای است که وظیفه انجام عملیات های مختلف CRUD را بر عهده دارد .این کلاسهای مخزن داده های از کلاس GenericRepository ارث بری میکنند که قبلاً در آن عملیاتهای مخلتف Select , Insert , Updateو Delete پیاده سازی شده است . در سورس زیر کلاس GenericRepository نمایش داده شده است .
[System.ComponentModel.DataObject]
public class GenericRepository<TEntity, TDataContext>

where TDataContext : DataContext
{
public static List<TEntity> SelectAll()
{
...
}
public static void Insert(TEntity entity)
{
...
}
public static void Update(TEntity entity)
{
...
}
public static void Delete(TEntity entity)
{
...
}
}
حالا نوبت به تعریف کلاسهای مخزن داده ای میرسد . این کلاسها که از کلاث فوق ارث بری میکنند نوع کلاس خود که آنها را با بانک اطلاعاتی متصل میکند بهمراه نام DataContex را بعنوان پارامتر ورودی کلاس وارد میکنند . در شکل زیر مراحل کار مشخص شده است .
//ProductRepository class
public class ProductRepository : GenericRepository<
Product, NorthwindDataContext>
{
}
در کد فوق کلاس Product و نام DataContext بعوان پارامترهای ورودی ارسال شده اند . توجه کنید این دو ورودی بصورت اتوماتیک توسط خود Visual Studio بصورت کاملاً ویزاردی تولید میشوند و شما کار اضافی انجام نمیدهید .

http://arjmandi.com/image.axd?picture=2009%2f11%2flinq.png
http://arjmandi.com/image.axd?picture=2009%2f11%2fsrc.png
اما کلاس ما یعنی کلاس ProductStaticRepository با استفاده از یک الگو یا T4 Template ایجاد میشود . این کلاس حاوی عملیاتهای استاندارد CRUD است .
حال در زمان صدا زدن این کلاس در لایه های بالا تر کافیست خطوط زیر را وارد نماییم .

var productRepository = new ProductRepository();
products = productRepository.SelectAll();

اما کدهای مربوط به عملیات SelectAll , Insert , ... قبلاً در یک لایه واسط تعریف شده اند . این لایه واسط GenericDataLayer میباشد . اگر قبلاً با Ado.net کار کرده باشید حتماً واسط SqlHelper رو بخاطر دارید که روالهای مانند ExecuteDataTable رو در اختیار برنامه نویس قرار میدادند . برای دسترسی این واسط بایستی از این آدرس (http://www.codeplex.com/MultiTierLinqToSql) استفاده کنید که آدرس مرجع اصلی این مقاله هم میباشد . در این تصویر لایه مورد نظر نمایش داده شده است .
استفاده از Generic به این معناست که من نیاز به نوشتن هیچ کدی در کلاس ProductRepository خودم برای انجام عملیات استاندارد CRUD ندارم و این ایمن ترین روش میباشد .
کلاس ProductRepository من امکان بهینه شدن را نیز دارد . این بدان معناست که من میتوانم در این کلاس روالهای اضافی مورد نیازم رو وارد کنم . مثلاً در مثال زیر ما یک Product رو براساس ID جستجو میکنیم . این کار با استفاده از کلمه کلیدی Partial امکان پذیر هست که به ما این امکان رو میده که به سادگی یک کلاس را به ماژولهای مختلف بشکنیم و در زمان کامپایل یک کلاس واحد داشته باشیم .
http://arjmandi.com/image.axd?picture=2009%2f11%2fgeneric_data_layer.p ng

namespace DataLayer{
public partial class ProductStaticRepository
{


public static IList GetByCategory(int id)
{
IQueryable res = SelectAll().Where(p => p.CategoryID == id);
return res.ToList();
}

public static void InsertBlank()
{
Product p = new Product { CategoryID = 1,

ProductName = "test", SupplierID = 1 };
Insert(p);
}
}
}
یکی از امکانات لینک امکان کنترل خطاها در این سطح میباشد . این خطاها بصورت رخدادهایی هستند که لینک به شما امکان پیاده سازی آنها را میدهد . البته من شخصاً سعی میکنم کاربر اطلاعات غلط وارد فرم اطلاعات نکند اما این امکان به نوعی مهم کاری محسوب میشود . کد زیر نمونه پیاده سازی رخداد OnProductNameChanging میباشد . بازهم گزینه partial امکان اتصال کلاسها رو بهم فراهم میکنه . بدین ترتیب میشه سایر رخدادها رو پیاده سازی کرد .

using System;

namespace DataLayer
{
public partial class Product
{
partial void OnProductNameChanging(string value)
{
if (value == "")
throw new Exception("Product name cannot be empty");
}

}
}

T4 Template همانطور که قبلاً گفتم برای ایجاد کلاسهای مورد نیاز از یک الگو استفاده میکنیم . برای این کار نیاز به دو فایل DataClasses.tt و L2ST4.ttinclude داریم . روش کار بصورت زیر میباشد :


ایجاد یک پروژه از نوع Class Library برای لایه داده ها
http://arjmandi.com/image.axd?picture=2009%2f11%2fclass-library.png
ایجاد یک مخزن داده لینک (DataContext) به پروژه و تغییر نام آن به DataClasses.dbml . (باید نام این فایل با نام فایل الگو یکسان باشد ) . بعد از آن اضافه کردن جداول بانک اطلاعاتی مورد نظر به لینک .
http://arjmandi.com/image.axd?picture=2009%2f11%2fdatacontext.png
اضافه کردن دو فایل الگو به پروژه . در این لحظه باید پیام اخطار زیر بروی صفحه ظاهر شود که مربوط به تولید خودکار کد توسط فایل الگو میباشد . با زدن دکمه OK فایل مورد نظر تولید میشود .


http://arjmandi.com/image.axd?picture=2009%2f11%2falert.png


در این مرحله باید کتابخانه GenericDataLayer به پروژه اضافه شود و فایل DataClasses.generated.cs که توسط MSLinqToSQLGenerator تولید شده و در کنار فایل DataClasses.dbml.layout در زیر DataClasses.dbml حذف شود تا فایلی که توسط T4 Template ایجاد شده جانشین آن شود . اکنون میتوانید پروژه را کامپایل نمایید .
http://arjmandi.com/image.axd?picture=2009%2f11%2fsolution.png
ادامه مطالب در پست بعدی

reza344
شنبه 07 اسفند 1389, 18:28 عصر
(قسمت دوم) (http://arjmandi.com/post/d9bedb8cd8a7d8afd987-d8b3d8a7d8b2db8c-d985d8b9d985d8a7d8b1db8c-da86d986d8af-d984d8a7db8cd987-d8a8d8a7-d8a7d8b3d8aad981d8a7d8afd987-d8a7d8b2-d984db8cd986daa9-%28d982d8b3d985d8aa-d8afd988d985%29.aspx)

مراحل ایجاد یک گرید با استفاده از GenericDataSource
نمایش اطلاعات :
1 - کتابخانه GenericDataLayer.dll که حاوی کلاس GenericObjectDataSource به پروژه اضافه شود . این کتابخانه جانشین کتابخانه ObjectDataSource میشود .
2 - کتابخانه لایه دیتا که در این مثال NorthwindDataLayer.dll میباشد به پروژه اضافه شود .
3 - اشیاء GenericObjectDataSource و گرید به صفحه اضافه شوند .
4 - گرید مربوطه به شی GenericObjectDataSource متصل شده و اشیاء مورد نظر جهت نمایش انتخاب شوند .

http://arjmandi.com/image.axd?picture=2009%2f11%2fimg01.png
5 - توجه شود که برای گرید کلاس ها ی static انتخاب شوند .
6 - جهت انتخاب صفحه به صفحه گرید بایستی گزینه EnablePaging مربوط به GenericObjectDataSource روی True قرار گیرد .
7 - جهت فعالسازی مرتب سازی اطلاعات گزینه SortParameterName مربوط به GenericObjectDataSource با مقدار sortExpression پر شود . این متغیر از طریق گرید مقدار دهی می شود .
8 - زمانیکه از GenericObjectDataSource گرید بصورت خودکار فیلد کلید را تشخیص نمیدهد به همین دلیل باید فیلد کلید را برای گرید مشخص نمایید . در این مثال (جدول Product) فیلد کلید ما DataKeyNames باید با مقدار ProductID پر شود .
9 - جهت نمایش اطلاعات فیلدهای که به سایر جداول متصل هستند باید ابتدا فیلد مورد نظر را بصورت TemplateField در آورد و سپس تنظیمات را انجام داده این تنظیمات مربوط به حالت نمایش و ویرایش میباشد . در تصویر زیر تنظیمات مربوط به حالت نمایش مشخص شده است . اینجا فواید استفاده از لینک مشخص میشود که براحتی شما به فیلد جدول دیگری دسترسی دارید . نکته دیگر مربوط به مرتب سازی اطلاعات این ستون میباشد که شما بایستی sortExpession را تنظیم نمایید که در تصویر زیر مشخص شده است .
http://arjmandi.com/image.axd?picture=2009%2f11%2fimg02.png
ماحصل خروجی در تصویر زیر مشخص شده .
http://arjmandi.com/image.axd?picture=2009%2f11%2fimg03.png
ویرایش اطلاعات :

10 - برای ویرایش نمودن اطلاعات بایستی در GenericObjectDataSource روالهای مربوط به ویرایش ، اضافه نمودن و حذف اطلاعات را تنظیم نمایید . این کار با استفاده از ویزارد دیتاسورس انجام میشود .
http://arjmandi.com/image.axd?picture=2009%2f11%2fimg05.png
بعد از اعمال تنظیمات :
http://arjmandi.com/image.axd?picture=2009%2f11%2fimg04.png
11 - برای ویرایش اطلاعاتی که به جداول دیگر مرتبط است بایستی از لیستهای کشویی DropDownList استفاده شود . برای اینکار نیاز به یک دیتاسورس جهت اتصال آن به موجودیت مربوطه است . نکته دیگر ردیفی از لیست میباشد که بایستی بصورت پیش فرض انتخاب شود .
کد مربوط به دیتا سورس :
http://arjmandi.com/image.axd?picture=2009%2f11%2fimg06.png
کد مربوط به ستون مورد نظر :
http://arjmandi.com/image.axd?picture=2009%2f11%2fimg07.png

فیلتر نمودن اطلاعات :
12 - در این مرحله قصد دارم بوسیله یک DropDownList اطلاعات جدول Product رو براساس Category فیلتر کنم . برای اینکار بایستی یک دیتاسورس برای DropDownlist و یک دیتا سورس برای گرید داشته باشیم و برای دیتاسورس گرید یک شرط بگذاریم که هر زمان آیتم انتخابی DropDownList تغیر کرد ، گرید ما نیز بر اساس آن فیلتر شود . اما این کار نیاز به یک روال داریم که آیتمهای جدول Product براساس CategoryID فیلتر بکنه . همانطور که در پست قبلی دید ما بوسیله Partial کلاسها میتوانیم روالهای اضافی خود را به کلاس اصلی اضافه کنیم . همانطور که در تصویر زیر می بینید این کلاس ایجاد شده است . توجه کنید که خط دستور بالای تعریف روال که با رنگ صورتی مشخص شده است جهت اضافه نمودن نام روال به ویزارد تنظیم دیتاسورس مورد نیاز است .

http://arjmandi.com/image.axd?picture=2009%2f11%2fimg08.png

اکنون ماحصل کار در تصویر زیر مشخص شده است که نام روال در لیست توابع اضافه شده است .
http://arjmandi.com/image.axd?picture=2009%2f11%2fimg09.png
در سورس برنامه میتوانید گرید مربوطه را مشاهده نمایید .

ورود اطلاعات با کد نویسی:
آخرین مطلب این پست در مورد کد نویسی مستقیم میباشد . قطعاً ما در یک پروژه نیازمندیم که بارها بصورت مستقیم اطلاعات را با کد نویسی وارد جداول نماییم . در این بخش سعی میکنم در جدول Shipper رکورد جدیدی وارد کنم . برای اینکار از دو Textbox کمک میگیرم .
http://arjmandi.com/image.axd?picture=2009%2f11%2fimg10.png
این مثال هم مربوط به پیمایش رکوردها میباشد :
http://arjmandi.com/image.axd?picture=2009%2f11%2fimg11.png
در این بخش این مطلب رو به پایان می رسانم . با استفاده آدرس زیر میتوانید سورس برنامه مثال را دریافت کنید . در پست بعدی سعی میکنم به این گرید امکان درج اطلاعات را اضافه کنم . Multi Layer With Linq to Sql.zip (541.18 kb) (http://arjmandi.com/file.axd?file=2009%2f11%2fMulti+Layer+With+Linq+to +Sql.zip)


منبع : یادداشتهای یک برنامه نویس ایرانی (http://arjmandi.com)