ارتقاء به Entity framework 6 و استفاده از بانک‌های اطلاعاتی غیر از SQL Server
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: سه دقیقه

برای ارتقاء برنامه‌های قدیمی به EF 6 (که با دات نت 4 به بعد سازگار است) دو حالت استفاده از نیوگت را در حین افزودن ارجاعات لازم به کتابخانه‌های مرتبط با EF باید مدنظر داشت:
الف) از نیوگت استفاده کرده‌اید
در این حالت فقط کافی است کنسول پاورشل نیوگت را در VS.NET گشوده و دستور update-package را صادر کنید. (1) به صورت خودکار آخرین نگارش EF دریافت شده و (2) همچنین فایل کانفیگ برنامه برای افزودن و به روز رسانی تعاریف مرتبط با نگارش 6 به روز گردیده و (3) همچنین اسمبلی اضافی و قدیمی System.Data.Entity.dll نیز حذف خواهد شد.

ب) اگر از نیوگت استفاده نکرده‌اید
ابتدا یک فایل متنی ساده را به نام packages.config با محتوای ذیل به پروژه خود اضافه کنید.
 <?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="5.0.0" targetFramework="net40" />
</packages>
سپس بر روی نام Solution در VS.NET کلیک راست کرده و گزینه فعال سازی Restore بسته‌های نیوگت را فعال کنید (انتخاب گزینه Enable NuGet Package Restore). در ادامه یکبار برنامه را Build کنید تا پوشه packages به صورت خودکار از اینترنت دریافت و بازسازی شود. اکنون دستور update-package را در کنسول پاورشل نیوگت صادر کنید. همان مراحل قسمت الف تکرار خواهند شد.

لازم به ذکر است، اگر پروژه شما از چندین زیر پروژه تشکیل شده است که هر کدام نیز ارجاعی را به اسمبلی EF دارند، باید فایل packages.config فوق را به این زیر پروژه‌ها نیز اضافه کنید. دستور update-package، زیر پروژه‌ها را نیز اسکن کرده و تمام ارجاعات لازم را به صورت خودکار به روز می‌کند. همچنین اسمبلی‌های قدیمی اضافی را نیز حذف خواهد کرد. به این ترتیب با تداخل نگارش‌های قدیمی و جدید EF مواجه نخواهید شد.


مشکلاتی که ممکن است با آن‌ها مواجه شوید:

الف) برنامه کامپایل نمی‌شود
تنها تغییری که جهت کامپایل برنامه باید انجام دهید، استفاده از فضاهای نام جدید بجای فضاهای قدیمی موجود در اسمبلی منسوخ و حذف شده System.Data.Entity.dll است. خود VS.NET قابلیت یافتن فضاهای نام مرتبط را دارد و یا اگر از Resharper نیز استفاده می‌کنید، این قابلیت بهبود یافته است. در کل مثلا System.Data.EntityState شده است System.Data.Entity.EntityState و امثال آن که به روز رسانی آن‌ها نکته خاصی ندارد .


ب) پروایدر بانک اطلاعاتی مورد استفاده یافت نمی‌شود
به صورت پیش فرض فقط پروایدر SQL Server به همراه بسته EF 6 است. حتی پروایدر SQL Server CE نیز با آن ارائه نمی‌شود. اگر از SQL Server CE استفاده کرده‌اید، باید دستور ذیل را نیز پس از نصب EF 6 صادر کنید:
 PM> Install-Package EntityFramework.SqlServerCompact
تا با خطای ذیل مواجه نشوید:
 No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlServerCe.4.0'.
Make sure the provider is registered in the 'entityFramework' section of the application config file.
See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.
استفاده از نیوگت به روشی که عنوان شد، فایل کانفیگ برنامه شما را جهت افزودن تعاریف پروایدرهای لازم، به روز می‌کند و این مورد در EF 6 الزامی است (حتما باید تعریف پروایدر در فایل کانفیگ موجود باشد).


ج) خطای عدم وجود کلید خارجی جدول Migration را دریافت می‌کنید
 The foreign key constraint does not exist. [ PK_dbo.__MigrationHistory ]
تا EF 5 نام کلید اصلی جدول MigrationHistory به صورت PK___MigrationHistory می‌باشد.
 ALTER TABLE [__MigrationHistory] ADD CONSTRAINT [PK___MigrationHistory] PRIMARY KEY ([MigrationId]);
در EF 6 این نام شده است PK_dbo.__MigrationHistory
برای حل این مشکل تنها کافی است دستورات ذیل را یکبار بر روی بانک اطلاعاتی خود صادر کنید تا نام مورد نظر به عنوان کلید اصلی جدول migration اضافه شود؛ در غیراینصورت اصلا برنامه اجرا نخواهد شد:
 ALTER TABLE [__MigrationHistory] drop CONSTRAINT [PK___MigrationHistory];
ALTER TABLE [__MigrationHistory] ADD CONSTRAINT [PK_dbo.__MigrationHistory] PRIMARY KEY (MigrationId);
البته یکبار برنامه را اجرا کنید. اگر خطای نبود کلید اصلی یاد شده صادر شد، آنگاه دو دستور فوق را اجرا نمائید.
  • #
    ‫۱۰ سال و ۱۱ ماه قبل، شنبه ۲۷ مهر ۱۳۹۲، ساعت ۰۳:۳۶
    با سلام
    توی یک برنامه سه لایه که edmx تو لایه DAL وجود داره به چه صورت میشه فضاهای نام رو update کرد

    • #
      ‫۱۰ سال و ۱۱ ماه قبل، شنبه ۲۷ مهر ۱۳۹۲، ساعت ۰۴:۲۷
      - توضیحات فوق مربوط به EF Code first بود و حتی با VS 2010 نیز قابل پیاده سازی و استفاده است.
      - برای حالت database first نیاز به VS 2013 دارید تا از کلیه امکانات EF 6 استفاده کنید (یا باید به روز رسانی خاصی را برای VS 2012 نصب کنید). حالت Code first مستقل است از IDE (یک مزیت دیگر).
      Entity Framework Designer همراه با VS 2012 فقط از EF 5 پشتیبانی می‌کند (در حالت پیش فرض) و از تغییرات انجام شده در EF 6 آگاه نیست. به همین جهت اگر با VS 2012 بخواهید با EF6 کار کنید (در حالت database first) باز هم همان اسمبلی قدیمی System.Data.Entity.dll را مورد استفاده قرار می‌دهد که در EF 6 اصلا کاربردی ندارد و با آن یکی شده است.
      البته در کل می‌تونید با VS 2012 هم در حالت database first با EF 6 کار کنید ولی نیاز به یک سری تغییرات دستی خواهید داشت (EF قدیمی و همچنین اسمبلی اضافی یاد شده را باید دستی حذف کنید) و به علاوه از بهبودهای جدید آن (در حالت پیش فرض و بدون به روز رسانی) محروم خواهید بود.
      Entity Framework Designer سورس باز نیست  (برخلاف هسته EF) و جزئی از VS.NET است. قرار است در آینده این افزونه را هم سورس باز کنند تا بتوانند مستقل از چرخه طول عمر VS.NET، خود EF Database first را نیز به روز کنند.
      ولی در کل اگر از Code first استفاده می‌کنید، EF6 حتی با VS 2010 هم سازگار است.
      - زمانیکه با یک ORM کار می‌کنید (فرقی نمی‌کند به چه اسمی)، لایه DAL همان ORM هست. (دست به اختراع لایه‌های اضافی نزنید)
      • #
        ‫۱۰ سال و ۱۱ ماه قبل، شنبه ۲۷ مهر ۱۳۹۲، ساعت ۲۲:۳۵
        البته برای استفاده کامل از امکانات entity6 در حالت‌های Model first و Database first در vs2012 می‌توانید vs2012 خود را با پکیچ زیر به روز کنید:
  • #
    ‫۱۰ سال و ۱۱ ماه قبل، سه‌شنبه ۳۰ مهر ۱۳۹۲، ساعت ۱۳:۲۸
    با تشکر از وقتی که میزارین برا این مقالات ارزنده .
    من وقتی به Entity framework 6  ارتقاء داردم مهمترین مشکلم این بود که t4 palmate هایی که برا scaffolding استفاده میکردم دیگه جواب نمیداد . مضمون ارورش  این بود که این ورژن از   Entity framework رو ساپورت نمیکنه  
  • #
    ‫۱۰ سال و ۱۱ ماه قبل، چهارشنبه ۱ آبان ۱۳۹۲، ساعت ۲۰:۳۶
    با سلام؛ من تازه 2 روزه با Entity Framework آشنا شدم. حالا به روی VS 2012 و از طریق manage nuget pachages و گزینه 6  Entity Framework را نصب کردم و برای قدم اول یک کلاس , یک data layer , و کانکشن استرینگ را هم طبق اون تنظیم کردم. اما در زمان اجرا خطای Could not find schema را برای کانفیگ در کانکشن استرینگ میده. از دوستان کسی میتونه راهنمایی کنه؟ ممنون میشم

    • #
      ‫۱۰ سال و ۱۱ ماه قبل، چهارشنبه ۱ آبان ۱۳۹۲، ساعت ۲۱:۵۵
      - برای اینکه از راه دور کسی بتواند به سؤالات شما پاسخ دهد، یک سری نکات را باید رعایت کنید. (برای مثال مشخص نیست تنظیمات رشته اتصالی شما چی هست؟ کجا و به چه صورت و ترتیبی تعریف شده. کدهای شما چطور تعریف شد‌ه‌اند که به این خطا رسیدید؟ اصل خطا، به صورت کامل و دقیق، به همراه stack trace آن چی هست؟ (ذکر اصل کامل خطا، مهم‌ترین قسمت پرسش شما باید باشد))
      - این خطا عموما زمانی حاصل می‌شود که محل تعریف connectionStrings در فایل کانفیگ قبل از configSections باشد. ترتیب این‌ها مهم است.
      - به علاوه صرفا تعریف یک کلاس لایه داده و رشته اتصالی کافی نیست . نیاز است مباحث migration را هم اضافه کنید. مراجعه کنید به سری EF Code first سایت و 5 قسمت اول آن‌را مطالعه کنید.
  • #
    ‫۱۰ سال و ۱۱ ماه قبل، پنجشنبه ۲ آبان ۱۳۹۲، ساعت ۱۵:۴۷
    یه نکته حاشیه ای: "ناگت" به تلفظ اصلی نزدیک تره تا نوگت یا نیوگت
  • #
    ‫۱۰ سال و ۱۰ ماه قبل، یکشنبه ۲۴ آذر ۱۳۹۲، ساعت ۰۳:۲۳
    با سلام؛ در صورت امکان مثالی از نحوه ایجاد بانک در اوراکل توسط code first رو قرار بدید.
  • #
    ‫۱۰ سال و ۴ ماه قبل، پنجشنبه ۸ خرداد ۱۳۹۳، ساعت ۲۳:۲۸
    با سلام،
    من یک پروژه مطابق ساختاری که در این مطلب ذکر شده ایجاد کرده بودم که البته با EF5 ایجاد شده بود. پس از ارتقاء پروژه به EF6 مشکلی که بوجود آمده این است که در حین اجرای آزمون‌ها، بانک اطلاعاتی بهمراه جدول migration ایجاد می‌شود ولی جداول در بانک اطلاعاتی ساخته نمی‌شود و EF تلاش می‌کند که migration‌ها را بر روی جداول اعمال کند، در صورتیکه عملاً جداول ایجاد نمی‌شوند.
    آیا از دوستان کسی با این مشکل مواجه شده است؟
  • #
    ‫۱۰ سال و ۱ ماه قبل، چهارشنبه ۲۹ مرداد ۱۳۹۳، ساعت ۰۴:۱۸
    با سلام؛ من از VS2013 و EF 6.1  استفاده می‌کنم ، مشکلی که وجود دارد  این است که ، با توجه به اینکه از Migrations  در لایه Datalayer.Migrations  اسفاده شده در زمان شروع برنامه در لایه  Web که MVC می‌باشد در قسمت Application_Start() از
      Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, Configuration>());
    استفاده شده که در ارسال هرگونه Query به لایه Serivce این error :
    An exception occurred while initializing the database. See the InnerException for details.  به وجود می‌آید و البته دیتابیس در SQL Server ایحاد شده و فقط در زمان ارسال هر گونه کوری به لایه سرویس این مورد پیش می‌آید .
    اما با جایگرین شدن در قسمت Application_Start() از
      Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, Configuration>());
    به :
       Database.SetInitializer<MoneyExDbContext>(null);
    مشکل حل می‌شود و ارسال هر گونه کوری به لایه سرویس بدون مشکل کار کرده .