مقایسه تجربی Entity Framework و NHibernate

اگر پست های اخیر این وبلاگ را خوانده باشید نباید با Entity Framework و NHibernate نا آشنا باشید. هر دو راه حلی برای دستیابی به داده ها در دات نت فریم ورک ارائه می کنند. Entity Framework محصول مایکروسافت است و NHibernate محصول جامعه اوپن سورس. من از هر دو در پروژه های واقعی استفاده کرده ام و در مورد هر دو نتیجه رضایت بخش بوده است. در این مطلب نتیجه یک مقایسه تجربی را میان Entity Framework و NHibernate خواهید خواند که امیدوارم شما را در انتخاب هر کدام از آن ها کمک کند.

نگاشت کلاس ها

در NHibernate برای انجام عمل Mapping کلاس ها، (با صرف نظر از کتابخانه های کمکی) به ازای هر کلاس باید یک فایل نگاشت XML و برای تنظیم آن نیز یک فایل XML نوشته شود. زمانی که یک دیتابیس داریم و می خواهیم کلاس های مدل خود را بسازیم NHibernate ابزاری برای این کار ندارد (با صرف نظر از ابزارهای کمکی) و باید نگاشت را به صورت دستی انجام داد. اما با استفاده از کتابخانه های کمکی مثل Fluent NHibernate می توان بدون نوشتن حتی یک خط کد XML نگاشت کلاس ها و تنظیم NHinernate را به خوبی انجام داد. ابزارهای Designer متعددی هم در حال حاضر برای نگاشت یک دیتابیس موجود برای NHibernate ساخته شده اند.

در Entity Framework انجام عمل Mapping با استفاده از Designer قدرتمند ویژوال استادیو به راحتی قابل انجام است و (با صرف نظر از نسخه جدید EF) این Designer فقط زمانی که یک دیتابیس وجود داشته باشد به کار می آید. شما می توانید ابتدا دیتابیس خود را بسازید و با Import کردن جدول های مورد نظر خود به صورت ویژوال عملیات Mapping را انجام دهید. سپس EF از روی آن، کلاس های دامین شما را با ارتباط های مناسب خواهد ساخت. در نسخه بعدی EF شما می توانید از روش هایی شبیه به Fluent NHibernate و Castle ActiveRecord برای ساختن کلاس های دامین خود و سپس نگاشت آن ها به یک دیتابیس استفاده کنید.

انجام پرس و جو

Entity Framework دو روش را برای ایجاد و اجرای کوئری ها به شما می دهد. یک روش، دستوراتی کاملاً شبیبه به SQL دارد به نام Entity SQL Language و روش دیگر روش محبوب LINQ to Entitis است که اکثراً از این روش استفاده می کنند. روش اول کاملاً شبیه به استفاده از زبان SQL است، فقط در اینجا به جای استفاده از نام جداول اطلاعاتی از نام کلاس ها و به جای نام فیلدها از نام پراپرتی ها استفاده می کنید. در روش دوم شما تمام قدرت LINQ را برای بدست آوردن نتایج از کلاس های دامین پروژه خود خواهید داشت.

در NHibernate برای کوئری گرفتن انتخاب های بیشتری دارید. این موضوع می تواند هم خوب باشد و هم بد! خوب است چون شما می توانید بر اساس نیاز خود و کاری که می خواهید انجام دهید یک روش را انتخاب کنید و بد است چون در بعضی مواقع باعث سردرگمی شما می شود. محبوب ترین روش در هر دوی این ORMها استفاده از LINQ است که تا نسخه قبلی NHibernate مشکلاتی در پشتیبانی کامل LINQ وجود داشت که در نسخه جدید تا حدود زیادی برطرف شده است. NHibernate از زبان HQL که یک SQL شیء گرا برای نوشتن کوئری است پشتیبانی می کند که برای کسانی که پیش زمینه SQL دارند کار را راحت می کند. Criteria API روش دیگری است که اگر نحوه استفاده از آن را یاد بگیرید تقریباً هر کوئری که نیاز داشته باشید را می توانید با آن بنویسید. در نسخه 3.0 NHibernate روش جدیدی به نام QueryOver اضافه شده که همان Criteria API را با استفاده از اکستنشن متدها و عبارت های lambda به صورت type safe ارائه می دهد. کوئری های نوشته شده به این روش شباهت زیادی به کوئری های نوشته شده با LINQ دارند. MultiQuery نام روش دیگری است که NHibernate را قادر می سازد که فقط با یک بار رفت و برگشت به دیتابیس چند کوئری را اجرا کند و نتایج آن را برگرداند.

سادگی در استفاده

فکر میکنم همه بدانیم که استفاده از Entity Framework در عمل از استفاده از NHibernate به مراتب ساده تر است. ابزارهایی که ویژوال استادیو برای ایجاد کلاس های دامین پروژه برای Entity Framework در اختیار شما قرار می دهد کار شما را بسیار آسان می کند. برای استفاده از EF شما نیازی به دانستن چیز خاصی ندارید و همین که کلاس های شما با استفاده از ویزارد ساخته شدند می توانید شروع به استفاده از آن ها کنید. اما در NH شما نیاز به یادگیری و مطالعه بیشتری دارید و احتمال برخورد به مشکل در آن نسبت به EF بسیار بیشتر است. اگر اهل مطالعه و یادگیری نیستید و در برنامه نویسی بی حوصله اید به هیچ وجه از NHibernate استفاده نکنید!

پشتیبانی از دیتابیس های مختلف

EF و NH هر دو از دیتابیس های محتلفی پشتیبانی می کنند. اما پشتیبانی کردن آن ها با یکدیگر تفاوت دارد. EF محصول مایکروسافت است و به صورت توکار فقط از SQL Server پشتیبانی می کند. برای دیتابیس های دیگر مثل اوراکل یا Sybase باید از پروایدرهای تجاری استفاده کنید. به تازگی MySql و SQLite پروایدرهای خود را برای EF ارائه کرده اند و اوراکل نیز قرار است در نیمه دوم سال 2011 این کار را انجام دهد. البته شما خودتان هم می توانید برای دیتابیس مورد نیاز خود یک پروایدر برای EF بنویسید.

در مورد NH چون یک محصول اوپن سورس است به صورت پیش فرض از دیتابیس های مختلفی مثل اوراکل، MySql، SQLite، SQL Server، Firebird پشتیبانی می کند.

Second Level Cache

استفاده از Caching در یک ORM معمولاً در دو سطح امکان پذیر است. سطح اول که در سطح تراکنش است و تضمین می کند که دو رکورد یکسان در یک Session دو بار خوانده نخواهند شد. سطح دوم Cache در سطح DAL انجام می شود و باعث بالا رفتن سرعت اجرای کوئری ها بدون اتصال دوباره به دیتابیس می شود و فقط محدود به یک Session نخواهد شد. EF  تا نسخه 4.0 این قابلیت را به صورت توکار ارائه نمی کند اما NHibernate تعدادی Provider مناسب برای این کار دارد.

کتابخانه های کمکی

در حال حاضر تعداد کتابخانه های کمکی NHibernate به علت کدباز بودن آن بسیار زیاد است. پروژه هایی مثل NHibernate Search و NH Validator که توسط جامعه کاربری توسعه می یابند برای EF وجود ندارند. برای EF باید به محصولات تجاری شرکت ها مراجعه کنید.

کارایی و سرعت

Entity Framework و NHibernate به اندازه کافی کارایی خوبی دارند اگر به درستی به کار گرفته شوند. نکته ای که وجود دارد این است که با EF شما به سختی می توانید اشتباه کنید اما در NHibernate اشتباه کردن به راحتی آب خوردن است! در Entity Framework بدون اینکه شما کاری انجام دهید، کارایی خوبی خواهید داشت اما در مورد NHibernate اینطور نیست. اگر مستندات NHibernate را کامل بخوانید و تمام ملاحظات کارایی را در پیاده سازی لحاظ کنید به کارایی و سرعت بالاتری از EF هم خواهید رسید.

زمان یادگیری

همانطور که گفته شد، یادگیری NHibernate معمولاً زمان بیشتری نسبت به Entity Framework نیاز دارد. با NHibernate شما نیاز به یادگیری مفاهیم بیشتری دارید و معمولاً برای حل یک مشکل زمان بیشتری را باید صرف کنید. هر دو، کتاب ها و منابع خوبی برای یادگیری دارند.

نتیجه

برای تصمیم گیری درباره استفاده از هر کدام از این ORMها فاکتورهای دیگری نیز موثر هستند که در این مطلب به آن ها اشاره نشد. NHibernate در حال حاضر انتخاب های بیشتری را نسبت به EF ارائه می دهد و شما کنترل بیشتری بر روی ویژگی های آن دارید. انتخاب های بیشتر باعث پیچیده تر شدن NH شده است. EF به جای آن از سادگی خاص محصولات مایکروسافت بهره می برد و برای راه اندازی یک پروژه که وقت کمی دارد بسیار مناسب است. هر چند انتخاب ها و ویژگی های بیشتر همیشه نکته مثبتی نیستند، چون اگر ندانید چطور انتخاب کنید و یا نحوه کار ویژگی مورد نظر را درک نکرده باشید، به راحتی می توانید اشتباه کنید. EF و NH هر دو وظیفه های مهم یک ORM را به خوبی انجام می دهند و کمی در جزئیات با هم متفاوت اند که در این مطلب به آن ها اشاره شد.

Advertisements

ویژگی جدید Code-first برای Entity Framework

با محبوب شدن NHibernate و کتابخانه های وابسته به آن مثل Castle ActiveRecord و Fluent NHibernate، مایکروسافت به تازگی ویژگی جدیدی را به صورت Preview برای ORM خود یعنی Entity Framework عرضه کرده است که قابلیت هایی جدیدی را به توسعه دهندگان می دهد تا به جای سر و کله زدن با ابزارهای Designer و فایل های نگاشت XML، بر کدهای شیء گرا تمرکز داشته باشند. با این ویژگی شما به راحتی می توانید مدل خود را با استفاده از کلاس های معمولی بسازید و از EF بخواهید تا دیتابیس را از روی مدل نوشته شده توسط شما بسازد.

نسخه ای که به تازگی عرضه شده آخرین نسخه کتابخانه Code first قبل از ارائه نسخه اصلی خواهد بود. برای دانلود این ویژگی جدید به این صفحه از سایت مایکروسافت بروید. بعد از نصب کتابخانه، برای استفاده از این ویژگی پروژه جدیدی از نوع Class Library ایجاد کنید و به فایل EntityFramework.dll در مسیر نصب شده ارجاع دهید. یک کلاس به نام Blog با محتویات زیر بسازید :

using System.Collections.Generic;<br />
using System.ComponentModel.DataAnnotations;<br />
using System.Data.Entity;</p>
<p>namespace BlogModel<br />
{<br />
public class Blog<br />
{<br />
[Key]<br />
public long ID { get; set; }</p>
<p>[Required(ErrorMessage="Title is required.")]<br />
public string Title { get; set; }</p>
<p>public bool ShowInSearchEngines { get; set; }</p>
<p>public string Description { get; set; }</p>
<p>public IList<Post> Posts { get; set; }<br />
}<br />
}

می خواهیم مدلی بسازیم برای نگهداری اطلاعات یکسری وبلاگ به علاوه پست ها و کامنت های هر کدام. در اینجا شما می توانید کلاس هایی ایجاد کنید که هر کدام نشان دهنده یک موجودیت در دیتابیس شما خواهند بود. این کلاس ها می توانند کلاس های ساده POCO باشند که نیازی ندارند از کلاس دیگری به ارث بروند تا نقش یک Entity را برای شما بازی کنند. این ویژگی به شما کمک می کند تا یک مدل ساده، قابل درک، تمیز و قابل تست برای پروژه خود بسازید. کلاس های مثال ما همگی POCO هستند.

using System.Collections.Generic;<br />
using System.Data.Entity;<br />
using System.ComponentModel.DataAnnotations;</p>
<p>namespace BlogModel<br />
{<br />
public class Post<br />
{<br />
[Key]<br />
public long ID { get; set; }</p>
<p>[Required(ErrorMessage="Title is required.")]<br />
public string Title { get; set; }</p>
<p>[StringLength(4000)]<br />
[Required(ErrorMessage="Content is required.")]<br />
public string Content { get; set; }</p>
<p>public Blog Blog { get; set; }</p>
<p>public IList<Comment> Comments { get; set; }<br />
}<br />
}

کلاس Post برای نگهداری اطلاعات یک پست وبلاگ نوشته شده است. Post با موجودیت Blog یک رابطه چند به یک و با موجودیت Comment یک رابطه یک به چند دارد که با استفاده از پراپرتی در آن مشخص شده اند. با استفاده از قابلیت های فضای نام DataAnnotations می توان مشخصات یک موجودیت را اعتبار سنجی نمود. این اعتبار سنجی با استفاده از تعریف Attribute بر روی مشخصات انجام می شود. به طور مثال پراپرتی Content در این موجودیت می تواند تا 4000 کاراکتر را در خود ذخیره کند و حتماً باید مقداری برای آن وارد شود وگرنه یک استثنا رخ خواهد داد که باید توسط برنامه نویس هندل شود.

using System.Data.Entity;<br />
using System.ComponentModel.DataAnnotations;</p>
<p>namespace BlogModel<br />
{<br />
public class Comment<br />
{<br />
[Key]<br />
public long ID { get; set; }</p>
<p>[Required(ErrorMessage="Name is required.")]<br />
public string Name { get; set; }</p>
<p>[Required(ErrorMessage="Email is required.")]<br />
public string Email { get; set; }</p>
<p>public string URL { get; set; }</p>
<p>[Required]<br />
public string Content { get; set; }</p>
<p>public Post Post { get; set; }<br />
}<br />
}<br />

استفاده از مشخصه های اعتبارسنجی باعث می شود که مدل ما به صورت خودکار در هنگام ذخیره در دیتابیس، اطلاعات خودش را مورد بررسی قرار دهد تا در صورت وجود یک داده نا معتبر از ذخیره شدن اطلاعات درون دیتابیس جلوگیری کند. برای اتمام مدل خودمان در این مثال فقط یک قدم دیگر مانده و آن هم ایجاد یک کلاس DbContext برای کلاس های ساده مان است :

using System.Data.Entity;</p>
<p>namespace BlogModel<br />
{<br />
public class MyBlogPlatform: DbContext<br />
{<br />
public DbSet<Blog> Blogs { get; set; }<br />
public DbSet<Post> Posts { get; set; }<br />
public DbSet<Comment> Comments { get; set; }<br />
}<br />
}<br />

در واقع این کلاس باعث می شود تا کلاس های ساده ی ما با دیتابیس بوسیله Map کردن کلاس ها به جدوال و پراپرتی ها به فیلدها و رابطه ها  ارتباط برقرار کنند. کدهای بالا تمام کدهای لازمی بود که ما برای ایجاد مدل و لایه دسترسی به داده های خود احتیاج داشتیم. آخرین مرحله قبل از استفاده از این مدل، مشخص کردن Connection String برای ایجاد دیتابیس از روی آن است که می توانید در web.config آن را به صورت زیر مشخص کنید :

<connectionStrings><br />
 <add name="MyBlogPlatform"  connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=MyBlogPlatform;Integrated Security=True"  providerName="System.Data.SqlClient"  />

EF Code first به صورت پیش فرض به دنبال رشته اتصالی در فایل web.config می گردد که با کلاس Context شما همنام باشد. چون کلاس Context ما در این مثال MyBlogPlatform است، EF هم به دنبال رشته اتصالی به همین نام خواهد گشت و از آن برای ایجاد دیتابیس یا اتصال به دیتابیس موجود استفاده خواهد کرد. برای اینکه مطمئن شویم کارمان مشکلی ندارد کدی برای ایجاد یک موجودیت بلاگ در دیتبایس در مکان مناسب (مثل کلیک یک دکمه در صفحه) می نویسیم :

MyBlogPlatform blogPlatform = new MyBlogPlatform();<br />
 Blog blog = new Blog()<br />
 {<br />
 Title = "Farasun",<br />
 ShowInSearchEngines = true,<br />
 Description = "A blog about programming"<br />
 };<br />
 blogPlatform.Blogs.Add(blog);<br />
 blogPlatform.SaveChanges();<br />
 

در این نقطه کار ما به پایان رسیده و شما قادر خواهید بود که با مدل خود کار کنید. EF تمام کارهای مربوط به دیتابیس را انجام خواهد داد و شما فقط باید بر روی قوانین تجاری و رابط کاربری اپلیکیشن خود وقت بگذارید. به طور مثال برای کوئری گرفتن توسط LINQ می توانیم چنین کدی برای مدل خود بنویسیم :

MyBlogPlatform myBlogPlatform = new MyBlogPlatform();<br />
 var query = from x in myBlogPlatform.Posts<br />
 where x.Title.Contains(“Entity Framework”)<br />
 select x;<br />
 

اگر سری آموزش های Castle ActiveRecord در این وبلاگ را دنبال کرده باشید، با این پست غریبه نبوده اید. اینطور که به نظر می رسد تیم Entity Framework راه درستی برای ادامه توسعه این پروژه انتخاب کرده و در آینده ای نزدیک باید شاهد قابلیت های بیشتری در جهت بهبود کارایی این ORM باشیم.

10 دلیل برای استفاده از ORM در دات نت فریم ورک

ORM یک تکنیک برنامه نویسی برای تبدیل مدل رابطه ای یک دیتابیس به مدل شیء گرا و بالعکس می باشد که در حال حاضر مورد توجه بسیاری از توسعه دهندگان نرم افزاری قرار دارد. استفاده از ORMها مزایای بسیاری دارد و در بسیاری موارد کار توسعه را آسان تر و لذت بخش تر خواهد کرد. برای دات نت فریم ورک ORMهای کدباز و تجاری زیادی وجود دارد که از این جمله می توان به ADO.NET Entity Framework و NHibernate اشاره نمود. من به شخصه از Entity Framework در یک پروژه واقعی استفاده کردم و تمام مزایایی که قبلاً در مورد یک ORM خوانده بودم را در واقعیت دیدم. در این مطلب به 10 دلیل برای استفاده از یک ORM در یک پروژه مبتنی بر دات نت فریم ورک اشاره خواهم کرد که به شخصه آن ها را تجربه کرده ام.

1- افزایش سرعت توسعه : طراحی لایه دسترسی به داده ها در یک برنامه تجاری معولاً زمان قابل توجهی را به خود اختصاص می دهد و کارهای تکراری مثل درج، به روز رسانی، حذف و خواندن رکوردهای دیتابیس به وفور در آن یافت می شود. استفاده از یک ORM می تواند زمان طراحی لایه دسترسی به داده ها را کاهش دهد یا حتی در مواردی نیاز شما به این لایه را از بین ببرد و شما را از نوشتن کدهای تکراری برای انجام اعمال بر روی دیتابیس راحت کند. اگر وقت زیادی صرف نوشتن کوئری های SQL به صورت رشته ای برای خواندن رکوردها و استفاده از آبجکت های ADO.NET برای درج، به روز رسانی یا حذف داده های یک دیتابیس می کنید، بهتر است در رویه برنامه نویسی خود تجدید نظر کنید و بقیه مزایای استفاده از یک ORM را تا انتها بخوانید!

2- رعایت الگوی طراحی شیء گرا : تفاوت ماهیت دیتابیس های رابطه ای با الگوی شیء گرا همیشه برای برنامه نویسان معضل بزرگی بوده و هست. کار اصلی ORM این است که جدوال رابطه ای یک دیتابیس را به کلاس های شیء گرا و بالعکس تبدیل کند و مدل سازی های مورد نیاز را به صورت استاندارد انجام دهد. هرچند در این روش نمی توان از برخی مفاهیم مهم طراحی شیء گرا مثل ارث بری یا چند ریختی استفاده کرد اما برنامه نویس را مجبور خواهد کرد تا حداقل قوانین های طراحی شیء گرایی را در پروژه خود لحاظ کند. استفاده از الگوی طراحی OOP باعث کاهش پیچیدگی پروژه و آسان تر شدن نگهداری کد و اعمال تغییرات بر روی آن خواهد شد.

3- کاهش پیچیدگی پروژه : شاید در ابتدا استفاده از یک ORM برای طراحی یک پروژه بزرگ ترسناک به نظر برسد! اما در واقع ORM برای کاهش پیچیدگی توسعه یک پروژه بوجود آمده است. استفاده از کلاس های شیء گرا برای کار با ساختار پایگاه داده برای یک برنامه نویس دات نت بسیار راحت تر از سر و کله زدن با کوئری های SQL برای رسیدن به نتایج مورد نظر یا انجام عملیات بر روی دیتابیس خواهد بود. در واقع کدهای مورد استفاده در پروژه ای که با یک ORM توسعه داده شده است به مراتب خواناتر از پروژه های دیگر است و حتی یک فرد غیر برنامه نویس نیز منظور کد را خواهد فهمید.

4- راحت شدن از دست SQL : برای کار کردن با جداول یک پایگاه داده زبان SQL زبان بی نقصی است، اما زمانی که قرار باشد از آن در یک زبان برنامه نویسی شیء گرا مثل سی شارپ استفاده شود، واقعاً عذاب آور خواهد بود. فرض کنید در تمام پروژه خود از دستورات SQL در متغیرهای string استفاده کرده اید، حال با تغییر نام یک فیلد بایستی به دنبال رشته نام فیلد مورد نظر، کل پروژه را بگردید و رشته جدید را جایگزین آن کنید و این کار به صورت خودکار انجام نخواهد شد. کامپایلر هیچ نوع کنترلی بر روی رشته های  SQL ندارد و یک اشتباه تایپی می تواند باعث ایجاد خطای در حال اجرا شود. استفاده از ORM می تواند شما را شر SQL راحت کند!

5- طراحی استاندارد لایه دسترسی به داده ها : در پیاده سازی ORMهای موجود تمام تجربه های موفق لحاظ شده اند و در نتیجه کدهای تولید شده توسط آن ها کاملاً بهینه و استاندارد هستند. ORM باعث می شود تا شما و بقیه اعضای تیم از یک استاندارد خاص برای طراحی لایه دسترسی به داده های خود پیروی کنید و در نتیجه بازدهی بهتری را شاهد باشید. این مزیت در آخر باعث بوجود آمدن یک ساختار مناسب در لایه دسترسی به داده های پروژه شما خواهد شد.

6- امکان استفاده از LINQ : در دات نت فریم ورک می توانید از زبان LINQ برای اجرای کوئری های مختلف در هنگام استفاده از یک ORM بهره ببرید. با این کار کامپایلر کنترل کاملی بر روی کوئری های نوشته شده دارد و تمام خطاها را شناسایی و گزارش خواهد کرد. به علاوه کوئری های نوشته شده در این حالت از خوانایی بسیار بالاتری برخوردار خواهند بود و می توانید از قابلیت های IntelliSense ویژاول استادیو برای بالا بردن سرعت کدنویسی و کاهش خطاهای انسانی بهره ببرید.

7- ORMها آزمایش خود را پس داده اند : در حال حاضر تعداد بسیار زیادی از پروژه های اوپن سورس پلت فرم دات نت بر پایه یک ORM توسعه یافته اند. با یک جستجوی کوچک می توانید لیست بلند بالایی از این پروژه ها را مشاهده کنید. تجربه های خوب بسیار زیادی هم از پروژه های تجاری که از ORM برای دسترسی به داده ها استفاده کرده اند در اینترنت وجود دارد. این نشان می دهد که ORMها آزمایش خود را پس داده اند و برای استفاده در پروژه های واقعی به اندازه کافی قابل اعتمادند.

8- نگهداری از کد و تغییر آن در دراز مدت آسان تر می شود : به علت پشتیبانی ORMها از الگوی طراحی شیء گرا و دیگر الگوهای طراحی در توسعه نرم افزار و تولید کدهای استاندارد، نگهداری از کدهای نوشته شده و تغییر آن ها در طولانی مدت بسیار آسان تر خواهد شد. کدهای نوشته شده بر مبنای یک ORM معمولاً بسیار واضح هستند و تغییر آن ها اگر به صورت استاندارد نوشته شده باشند، اصلاً سخت نخواهد بود.

9- استفاده از قابلیت Refactoring : فرض کنید نیاز دارید تا نام چند فیلد یا جدول را در دیتابیس خود تغییر دهید. اگر از ADO.NET و کدهای SQL برای طراحی لایه داده های خود استفاده کرده باشید، برای انجام این تغییرات در کدهای خود نمی توانید از قابلیت Refactoring ویژوال استادیو استفاده کنید تا به صورت اتوماتیک این کارها انجام شود. اما با استفاده از یک ORM، تغییر دادن یک موجودیت باعث به روز رسانی تمامی ارجاع های آن موجودیت در کل پروژه توسط قابلیت Refactoring ویژوال استادیو خواهد شد. این قابلیت می تواند خطاهای انسانی را فوق العاده کاهش و سرعت توسعه را افزایش دهد.

10 – عدم وابستگی به یک دیتابیس خاص : هر چند این نکته در مورد تمام ORMهای مخصوص دات نت فریم ورک درست نیست، اما در حال حاضر ORMهای خوبی مثل NHibernate و Entity Framework از چندین دیتابیس پر استفاده پشتیبانی می کنند. البته EF در حال حاضر به صورت رسمی فقط از SQL Server پشتیبانی می کند!

farasun.wordpress.com

توصیه می شود مطالبی که قبلاً دوستان در این مورد نوشته بودند را مطالعه کنید :

farasun.wordpress.com

عناوین دیگر برای این نوشته : چرا باید از یک ORM در دات نت فریم ورک استفاده کرد؟ | مزیت های استفاده از ORM در دات نت فریم ورک

راه های دسترسی به داده در دات نت فریم ورک!

در اکثر برنامه های کامپیوتری نیاز به ذخیره و بازیابی داده ها وجود دارد. داده هایی که بدون آن ها سیستم نرم افزاری ما معنایی ندارد. برنامه نویسان معمولاً راه های مختلفی برای این کار سراغ دارند. کسانی که با دات نت فریم ورک برنامه نویسی می کنند راه های مختلفی برای دسترسی به داده ها دارند. در این مطلب با تکنولوژی های مایکروسافت برای این کار آشنا خواهیم شد و سه ORM معروف دنیای دات نت را معرفی خواهیم کرد. مایکروسافت انتخاب های زیادی برای دسترسی به داده ها به برنامه نویسان دات نت می دهد که شما باید با بررسی آن ها و با توجه به نیازهای خودتان یکی از آن ها را انتخاب کنید.

ADO.NET

ADO.NET مجموعه ای از کامپوننت هاست که برنامه نویسان می توانند از آن ها برای برقراری ارتباط با دیتابیس های مختلف استفاده کنند. ADO.NET بخشی از کتابخانه کلاس های پایه دات نت فریم ورک است که توسط مایکروسافت توسعه داده می شود. برنامه نویسان به صورت گسترده از این تکنولوژی برای دسترسی و دستکاری داده های ذخیره شده در یک دیتابیس رابطه ای استفاده می کنند. ADO.NET می تواند با اکثر دیتابیس های موجود کار کند، هر چند به صورت پیش فرض در دات نت فریم ورک فقط فراهم کننده های SQL Server، OleDb و Odbc وجود دارد، افراد و شرکت های دیگر فراهم کننده های دیتابیس های دیگر را برای دات نت ایجاد کرده اند.

برای هر Provider کامپوننت هایی وجود دارند که برنامه نویس با استفاده از آن ها به مقصودش می رسد. به طور مثال برای استفاده از SQL Server در روش ADO.NET کامپوننت هایی مانند SQLConnection و SQLCommand وجود دارد که با استفاده از آن ها می توانید یک دستور SQL را روی داده های موجود در یک دیتابیس SQL Server اجرا کنید. با SQLConnection به دیتابیس موجود در SQL Server وصل می شویم و با استفاده از یک SQLCommand می توانیم یک عبارت T-SQL را که می تواند دستور INSERT, UPDATE, DELETE یا SELECT باشد یا حتی یک Stored Procedure یا عبارت DDL باشد را برای مقصود خاصی روی دیتابیس اجرا کنیم. چون ADO.NET در مورد سینتاکس دیتابیس چیزی نمی داند، دستورات را به صورت یک رشته ساده به SQLCommand می دهیم و این شیء نیز به صورت مستقیم به دیتابیس دستور می دهد.

string query = "SELECT * FROM tblCustomers";
SqlConnection con = new SqlConnection(cnnString);
SqlCommand command = new SqlCommand(query, con);
con.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Response.Write(reader.GetInt32(0) +
reader.GetString(1));
}

نکته ای که باید در مورد ADO.NET بدانید این است که برای استفاده از هر سیستم دیتابیس رابطه ای، مجموعه کامپوننت های جدایی وجود دارد. در مثال بالا از آبجکت های مربوط به SQL Server استفاده کردیم. اگر بخواهید مثلاً از یک دیتابیس اوراکل در برنامه خود استفاده کنید، بایستی از کامپوننت های مربوط به اوراکل استفاده کنید. خوشبختانه تمام این کامپوننت ها بر پایه یک Interface ساخته شده اند، این یعنی شما می توانید با استفاده از کلاس DbProviderFactory برنامه ای بسیازید که با چند نوع دیتابیس مختلف کار کند.

Linq to SQL

مایکروسافت با دات نت فریم ورک 3.0 و 3.5 یک ORM به نام Linq to SQL را به عنوان بخشی از پروژه LINQ خود عرضه کرد. این شرکت مدت ها پیش از آن قول داده بود که یک ORM برای دات نت فریم ورک طراحی کند اما تا نسخه 3.0 دات نت فریم ورک خبری از آن پروژه نشد. Linq to SQL به شما اجازه می دهد که کوئری های LINQ را روی دیتابیس های SQL Server اجرا کنید. علاوه بر این از یک Mapping Framework بهره می برد که به برنامه نویسان اجازه Map کردن جدول های یک دیتابیس را به کلاس ها و بالعکس می دهد. این کار در ویژوال استادیو می تواند به صورت ویژوال یا کدنویسی انجام گیرد. به این صورت که برای هر جدول از دیتابیس یک کلاس تعریف می شود که هر ستون از یک جدول به عنوان یک Property درون آن کلاس تعریف می شود.

نمایی از ابزار طراحی ویژوال Linq to SQL

به مثال زیر توجه کنید :
public class Customer
{
[Column(Name="CustomerID",IsPrimaryKey = true)]
public long ID
{
get { return _ID;}
set { _ID = value;}
}
[Column(Name = "CustomerName")]
public string Name
{
get { return _name; }
set { _name = value; }
}
}

کلاس بالا به جدول tblCustomers که دارای دو ستون CustomerID و CustomerName است Map می شود. قبل از اینکه بخواهید از Linq to SQL استفاده کنید باید این کلاس ها را تعریف کنید. ویژوال استادیو 2008 دارای ابزاری است که به صورت ویژوال به شما امکان Map کردن جدول های یک دیتابیس SQL Server را به کلاس های دات نت می دهد. این ابزار می تواند به صورت اتوماتیک کلاس های مورد نیاز شما را از روی مدل دیتابیس بسازد، و حتی اجازه تغییرات دستی و ایجاد Viewهای مختلف از دیتابیس را به شما می دهد. عملیات Mapping با استفاده از DataContext (که یک رشته اتصال به سرور نیاز دارد) پیاده سازی می شود. سپس شما قادر خواهید بود کوئری های LINQ خود را روی دیتابیس موجود در سرور اجرا کنید، که البته این کوئری ها ابتدا به دستوارت T-SQL متناظر ترجمه و سپس روی دیتابیس مورد نظر اجرا می شوند.

Entity Framework

Entity Framework یک فریم ورک ORM برای دات نت فریم ورک است که نسخه یک آن به همراه دات نت فریم ورک 3.5 سرویس پک 1 عرضه شد اما مورد استقبال توسعه دهندگان قرار نگرفت. نسخه 2 این فریم ورک به صورت بتا به عنوان بخشی از ویژوال استادیو 2010 قابل دسترس است. ADO.NET Entity Framework نام اصلی این فریم ورک است و جزئی از تکنولوژی ADO.NET است.

ابزار طراحی Entity Framework در ویژوال استادیو

ابزار طراحی Entity Framework در ویژوال استادیو

Entity Framework مدل رابطه ای موجود در یک دیتابیس را به مدل مفهمومی تبدیل می کند و آن را به اپلیکیشن ما تحویل می دهد. در مدل رابطه ای عناصر ترکیبی از جداول هستند، به همراه کلید های اصلی و خارجی که جدول ها را به هم مرتبط می سازند. برعکس آن، انواع موجودیت ها مدل مفهومی داده را تعریف می کنند. انواع موجودیت  اجتماعی از چند فیلد است (هر فیلد به یک ستون از دیتابیس Map می شود) و می تواند شامل اطلاعات از چند جدول فیزیکی باشد. انواع موجودیت می توانند به هم مرتبط باشند، مستقل از ارتباطاتی که در مدل فیزیکی دارند. شمای منطقی و نگاشت (mapping) آن به شمای فیزیکی به عنوان یک Entity Data Model یا EDM نمایش داده می شوند که مشخصات EDM در یک فایل XML ذخیره می شود. Entity Framework از EDM برای انجام عملیات نگاشت و دادن قابلیت کار با موجودیت ها به اپلیکیشن استفاده می کند. Entity Framework اطلاعات مورد نیاز هر موجودیت را با Join کردن چندین جدول از مدل فیزیکی (دیتابیس) بدست می آورد. هنگامی که اطلاعات یک موجودیت آپدیت می شود، Entity Framework بررسی می کند که داده ها مربوط به کدام یک از جدول های موجود در دیتابیس هستند، سپس آن ها را با دستور SQL مناسب آپدیت می کند.

هر چند Entity Framework و Linq to SQL بسیار شبیه به هم به نظر می رسند، هر دو ابزارهایی برای طراحی گرافیکی و ویزاردی برای نگاشت یک دیتابیس به مدل شیء گرا دارند و هر دو می توانند از کوئری های LINQ برای مقصود خاصی استفاده کنند، اما با هم تفاوت هایی هم دارند. بیان تفاوت های این دو در این مطلب جایی ندارد.

NHibernate

نمی توان در مورد ORMها در دات نت صحبت کرد اما نام NHiernate را ذکر نکرد. NH یک فریم ورک ORM اوپن سورس برای دات نت فریم ورک است که از روی پروژه موفق Hibernate جاوا وارد دنیای دات نت شد. توضیحات بیشتر در مورد NHibernate توضیحات اضافی است، زیرا این فریم ورک هم وظیفه ORMهای دیگر را انجام می دهد. اکثر برنامه نویسانی که از NH برای نگاشت استفاده می کنند، ابتدا کلاس های خود را تعریف می کنند و سپس با استفاده از یک فایل XML آن ها را به جدول های دیتابیس Map می کنند. Linq to SQL و Entity Framework برخلاف NHibernate از روش Model-first یا مبتنی در دیتابیس استفاده می کنند، به این معنی که هر دو ORM تصور می کنند شما دیتابیسی در اختیار دارید که می خواهید آن به تعدادی آبجکت Map کنید.

در مورد Nhibernate بیش از این صحبت نمی کنم، آقای وحید نصیری در اینجا به صورت کامل در مورد این ORM محبوب نوشته است.

farasun.wordpress.com

انتخاب از میان روش های بالا به عهده خود شماست. در این مطلب کوتاه نمی توان به بررسی تمام زوایا و تفاوت های میان آن ها پرداخت. در مطالب آینده سعی میکنم در مورد نحوه استفاده از هر کدام یک مثال عملی بزنم (البته به جز NHibernate).