NHibernate، دات نت

مقایسه تجربی 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 را به خوبی انجام می دهند و کمی در جزئیات با هم متفاوت اند که در این مطلب به آن ها اشاره شد.

17 نظر برای “مقایسه تجربی Entity Framework و NHibernate

  1. اولاً که EF از همان اولین نسخش از Model First پشتیبانی می کرد.
    دوماً از 2 سال پیش که EF اومد، همون موقع هم کلی پرووایدر برای دیتابیس های مختلف واسش اومد. مثلاً Connector/Net که خود MySQL به صورت رایگان و نه تجاری عرضه کرد و خیلی از پرووایدرهای رایگانی که در CodePlex و سایت های دیگه وجود داره.

    1. @ خفنوویچ : من جایی در نوشته ام نگفتم که EF از Model First پشتیبانی نمی کرده یا نمی کند. و همینطور جایی هم نگفتم که پروایدرهای رایگان برای EF وجود ندارد.

      1. گفتی:
        اینجا:
        در Entity Framework انجام عمل Mapping با استفاده از Designer قدرتمند ویژوال استادیو به راحتی قابل انجام است و (با صرف نظر از نسخه جدید EF) این Designer فقط زمانی که یک دیتابیس وجود داشته باشد به کار می آید.

        و اینجا:
        برای دیتابیس های دیگر مثل اوراکل یا Sybase باید از پروایدرهای تجاری استفاده کنید. به تازگی MySql و SQLite پروایدرهای خود را برای EF ارائه کرده اند و اوراکل نیز قرار است در نیمه دوم سال 2011 این کار را انجام دهد.

        دو جمله ی فوق اشتباه هستند 🙂

      2. @ خفنوویچ :
        درستش چي هست؟ هدف از بحث، فراگيري است و به اشتراك گذاري اطلاعات. هدف كل‌كل بي حاصل نيست.
        پروايدر تجاري اوراكل و خبرش:

        Click to access oracle-entity-framework-sod-130214.pdf

        بنابراين ساپورت رسمي از طرف اوراكل در 2011 خواهد بود و مطلب عنوان شده صحيح است.

    1. چرا فکر می کنی کل کل می کنم؟ من هم هدفم روشن شدن حقایق هست. جالبه که بحث رو گلچین می کنی و به اونهایی که دوست داری پاسخ میدی. مثلاً در مورد MySQL که پرووایدر رایگان داره حرفی نمی زنی و چون یک مدل تجاری برای Oracle پیدا کردی، تمام بحث رو صرفاً به سمت اون سوق میدی و با اون میخوای نشون بدی که EF فقط از SQL Server پشتیبانی می کنه. این هم یک لینک برای پرووایدر Oracle:
      http://oracleef.codeplex.com/
      اینجا یک یک نسخه ی Express رایگان برای Oracle وجود داره:
      http://www.devart.com/dotconnect/oracle/download.html

      سوال اینجاست که اگر شرکتی دوست نداشت برای دیتابیسش پرووایدری برای سازگاری با یک تکنولوژی ارائه کنه و دیگران این کار را کردند، شما همه همیشه همه جا اعلام می کنی که برای فلان DBMS هیچ پرووایدری برای فلان تکنولوژی وجود نداره؟

      و اما بریم سراغ قسما دوم پاسخت:
      دوست عزیز من، Model First با Code First فرق می کنه! واضح هست که EF از Code First و POCO از اولین نسخه پشتیبانی نمی کرد اما صحبت من در مورد Model First بود. لطفاً با دقت بیشتری مطالب رو بخون.

      موفق باشی 🙂

    2. در ضمن، عبارت «Model First یا Code First» هم غلط هست. در اون لینکی که دادی در مورد Code First صحبت شده و وجود عبارت «Model» شما رو به اشتباه انداخته. نویسنده ذکر کرده که شما می تونی «مدل رو با استفاده از کلاس های #C ایجاد کنی». این «مدل» اون مدلی نیست که شما فکر کردی. در Model First با استفاده از Designer، موجودیت ها و روابط بین اونها ایجاد میشه و از روی اون «مدل» EF دیتابیس رو ایجاد می کنه.

      1. مدل يعني يك كلاس. يك كلاس سي شارپ يا كلاس وي بي دات نت و امثال آن. در اون سايت هم ذكر شده Code First allows you to define your model using C# or VB.Net classes . خوب آيا نگارش فعلي اين اجازه‌ي تعريف model را به صورت كلاس در ابتداي كار مي‌دهد؟ به صورت مستقل از هر چيزي؟
        كلاس ادبيات كه نيست دوست عزيز واژه معنا مي‌كني.

  2. مطلب جالبی بود. فقط چند نکته!

    1. چرا نسخه نهایی EF را مورد مقایسه قرار نمی‌دهید (نسخه 4 که از ModelFirst پشتیبانی می‌کند). در زمانی که EF 4 وارد بازار شد، NH هنوز پیشتیبانی کاملی از LINQ نداشت.
    2. متاسفانه یا خوشبختانه معمولاً در مورد محصولات مایکروسافت این اشتباه وجود دارد که آنها را در دید اول ساده می‌دانند و بس! همین سادگی باعث ایجاد این تصور می‌شود که سادگی != قدرت. همیشه در این چنین محصولاتی یک راه ساده و کم قدرت در کنار یک راه پیچیده و پرقدرت وجود دارد. در مورد EF نیز امکانات خوبی وجود دارد که نیاز به مطالعه و مهارت بیشتری دارد و اگر به درستی از آنها استفاده شود نتایج خوبی به دست می‌آید. همین عامل باعث می‌شود که مبتدی‌ترین برنامه‌نویسان در کنار قوی‌ترین آنها با یک تکنولوژی کار کنند. اما این کجا و آن کجا.
    3. در ضمن یکی از بزرگترین محاسن EF 4 که من نمی‌دانم در NH وجود دارد یا خیر این است که در EF هنگامی که ModelFirst کار می‌کنید می‌توانید استراتژی ایجاد بانک اطلاعت را با استفاده از Workflow 4 و T4 خودتان مشخص کنید. البته افزونه‌های آماده خوبی برای اینکار وجود دارد که حداقل به راحتی از دو حالت TablePerType و TablePerInheritance پیشنیبانی می‌کند که به شخصه برای من از اهمیت بسیار بالایی بر خوردار است و یکی از مهمترین دلایلم در استفاده از EF همین است. شما که با NH بیشتر کار کرده‌اید بهتر می‌توانید در این مورد EF و NH را مقایسه کنید.

    ممنون.

    1. @ امیر : ممنون
      1- در اینجا NH با EF 4.0 مقایسه شده و همونطور که گفتم من در نوشته ام نگفتم که EF از Model First پشتیبانی نمی کند. فقط گفتم که در نسخه بعدی این مورد بهبود زیادی پیدا کرده است.
      2- شاید از این نوشته برداشت شود که EF بخاطر سادگی، قدرت کمی دارد. اما من همینجا به قدرتمند بودن Entity Framework مایکروسافت اعتراف می کنم!! چون از اون در یک پروژه واقعی استفاده کرده ام.
      3- EF در نسخه بعدی بهبودهای زیادی پیدا خواهد کرد و دور از انتظار نخواهد بود که حتی NH را از نظر داشتن ویژگی های جدید تر پشت سر بگذارد. اگر اشتباه نکنم S#harp Architecture از T4 Template برای ایجاد کلاس های POCO پشتیبانی می کند.

بیان دیدگاه