متن صدای این ویدیو : 

خب دوستان تو این قسمت از کدنویسی سمت server میخوایم راجع به Entity Framework  صحبت کنیم و این ویدئو ویدئوی مهمی هست .

 هر نوع کار و قابلیتی که شما  از طریق visual studio  برای Entity Framework در Console Package Manager دارید  که اصلی ترین آن migration  هست  ، توی پلتفرم خودکار هم میتونید انجام بدید .  

Migration  کاری که انجام میده برای شما اینه که تاریخچه و history  تغییرات Database  تون رو نگه میداره تا هر آن که بخواید ورژن Database رو عوض کنید به ورژن های قدیمی تر برگردونید یا اگه پشیمون شدید برگردونید به ورژن جدیدتر.

من قبل از اینکه این قضیه را توضیح بدم یکبار جداول Database رو برای شما توضیح میدم .

 از قسمت توسعه ، مدیریت کدها ، کدهای تحت Database ، کدهای تحت Sql Server را انتخاب میکنید، ارتباط پیش فرض و از قسمت کوئری های سیستمی اطلاعات دقیق تر جداول ، تو این قسمت که شما بیاین ، از انتخاب فایل که بزنید یک کوئری اینجا هست ....  

انتخاب فایل رو میزنید کوئری رو باز میکنید ، یک سری select  داره توش ، من این select  اولش رو انتخاب کردم و این ستون های اضافی رو که نمیخواستم برداشتم و نهایتش select  ام شده به این شکل . 

Ctrl A + Ctrl E   میزنم تا اجرا بشه. خب این لیست تمام table  های من بر اساس اسکیما ها هست . ما تو دیتابیس 2 تا اسکیما داریم ، یعنی وفتی پلتفرم خودکار شما نصب میشه 2 تا اسکیما هم نصب میشه . 

یکی content management  که کارهای CMS  رو انجام میده و یکی هم اسکیما security  هست که همون جداول AspNetIdentity هست 

الان همینطور که مشادهده میکنید این Database  فعلی من هست قبل از کار با Entity Framework 

وقتی پلتفرم خودکار رو نصب میکنید یک sample  برای شما هست که بتونید از اون استفاده کنید من میرم به قسمت  کدهای تحت سیستم عامل، کدهای تحت دات نت، مدیریت اسمبلی ها ،فرض کنید که ما الان میخوایم روی platform  وبسایت خودمون رو شروع به ساخت کینم .

 اولین کاری که باید بکنیم اینه مدل رو بسازیم ، یعنی اون  بیزینس مدل (business model)  رو  که از روی اون باید بتونیم جداول رو بسازیم ، من لایه مدل برای شما تو قسمت (framework) فریم ورک  خودکار ، sample قرار داده شده باز میکنیم KS.Dynamic.model.dll  یه اسمبلی کامپایل(Compile)  نشده هست ، تو قسمت خود کد Dll دو تا جا نمایی برای name space داره . یکی Model.Base و یکی هم خود Model . 

تو وابستگی هاش هم که میبینید ، توی فریم ورک خودکار توی اسمبلی های  مرکزی خودکار KS.Core ، رفرنس شده و تو سایر اسمبلی ها  ، EntityFramework ، EntityFramework.Extended  وEntityFramework.sqlserver و system.componentmodel.annotations. 

این از Dll  های فریم ورک خودکار ، توی اسمبلی های سیستم هم ، System.dll رو بهش reference شده . و خب طبعا مکان ذخیره ش هم از نوع Output هست ، چون لایه UI نیست که ما بخوایم publish کنیم .

 خب من این ها رو دونه دونه فضای namespace برای شما توضیح میدم . اول name space  با نام Model رو . خب توی این Sample فقط ما یه دونه  model  رو  به عنوان تست برای شما ساختیم ، یعنی یه جدول داره اونم DynamicTestModel هست که حالا یه field  با نام name  داره و این از BaseEntity ارث برده.

 حالا من BaseEntity هم برای شما توضیح میدم و توی فضای نام Model.Base

همینطور که مشاهده میکنید ما اینجا یه کلاس BaseEntity داریم که abstract هست معنیش اینه که نباید براش جداولی ساخته بشه و فقط ازش ارث میبریم .

 ما field  های مشترک همه جداول مون رو ،field  هایی که برای Log  هست یا برای چک کردن Access  هست ، مثله Creator User ID ، Modifier User ID ،  CreateDateTime این ها رو میام تو BaseEntity تعریف میکنیم یکبار و همه جا تو  بقیه َ Entityها از اون ارث میبریم  و اگر یکبار این رو تغییر بدید تو تمام Entity  ها  update میشه  حالا ما field  هایی که اینجا داریم Language ، CreateUserId ، ModiferUserId ، CreateLocalDateTime  و CreateDateTime  

فرق این LocalDateTime ها با بقیه DateTime ها در این است که ، شما ببینید وقتی که وبسایت تون رو روی server انتشار می دهید ، ممکنه که اون سرور cloud باشه و اصلا اون تاریخ معلوم نیست به تاریخ و ساعت کدوم کشور هست .

 اینجا شما توی CreateLocalDateTime ، توی وبکانفیگ میتونید تنظیم بکنید . تنطیماتی هست که توی قسمت مدیریت وب کانفیگ هست ، Local datetime  کجا باشه ، مثلا میزنید +3:30 برای تهران ، اون وقت یک Local date time   ثابت دارید که تاریخ و date time تهران رو برای تمام جداول تون و هر record رو با اون تاریخ local  که شما خواستید ثبت میکنه و از اون طرف اون سه تا تاریخ دیگه هم حتما به تاریخ GMT، یعنی با تاریخ ساعت گرینویچ برای شما ثبت میشن که بعدا به هر تاریخ و ساعت محلی دیگه ایی که  برای user  تون خواستید، بتونید تبدیلش کنید . اما خود BaseEntity  همونطور که میبینید از ILogEntity و IAccessRole ارث برده . این دو تا name space  در اصل وقتی شما ازشون ارث میبرید دارید از framework سمت server خودکار استفاده میکنید .

 این دو تا برای  log  کردن و چک کردن عملیات امنیتی (IAccessRole) همون ViewRoleId و ModifyRoleId  و AccessRoleId  رو داره که ما تمام جداول مون برای تک تک records این 3 تا نقش (role) رو داره نقشی که کی میتونه به این record دسترسی پیدا کنه کی میتونه  record رو ببینه و کی میتونه record رو ویرایش بکنه . توی ILogEntity هم که عرض کردم خدمتتون Create  ها هستن ، تاریخ وساعت local  و تاریخ و ساعت های گرینویچ .اینم از مدل  Base. 

وقتی ما مدل مون رو ساختیم نوبت میرسه به لایه data Access  ، خب من DLL با نام Data Access  رو برای شما باز میکنم. 

تو data access  هم باز میبینید تو خود Dll یه جا نمایی namespace ها هستند و وابسته هم هستند به KS.Dynamic.Model.Dll یعنی model  مون reference  شده که بتونیم از model  هامون استفاده کنیم و حالا باقی وابستگی هاست ، System.dll ، System.Core.dll ، .System.Data.Dll ، اسمبلی های سیستمیش هستند  و توی framework  خودکار هم که حتما KS.Core.Dll هست برای اینکه از framework سمت server  خودکار استفاده کنیم و KS.Dynamic.Model و سایر اسمبلی ها هم که EntityFramework ها هستند.

  اینم ازreference هامون ، خب اولین namespace ای که من میخوام توضیح بدم خود contexts  هست ، توی این namespace ما اومدیم context  رو تعریف کردیم یک  context  من ساختم برای sample  به اسم DynamicContext، که interface ش هم IDynamicContext هست همون  Dynamic test model  هم داخلش هست .

باز اگر دقت کنید تو اینجا Dynamic context هم از base context  ارث برده، من base context  هم برای شما توضیح میدم ، به فضای نام  context.base  می ریم و بزرگش میکنم و این source  ها هم همه کپی شده هستند از source  خود پلتفرم خودکار  ، یعنی source  پلتفرم خودکار که در اختیارشما باشه خیلی ساده میتونید با  copy-paste لایه های خودتون رو توسعه بدید.

خب تو این قسمت چون گفتم کپی شده یه سری از امکانات framework  هم برای شما هست . مثله log  کردن و چک کردن دسترسی ها .. ، مثلا همون ILogEntity که دیدید ، اینجا وجود داره برای اینکه یک مقادیری هنگام save کردن به صورت اتوماتیک براش ذخیره بشه حالا امکاناتی دیگه ای هم داره که توی ویدئو های مربوط به source قرار میدیم . اینم ازbase context  .

فضای نام بعدی قسمت Context.Config هست . شما تو این قسمت میتونید مدلتون رو Config کنید کلید خارجی ، کلید اصلی به وسیله ی fluent api entity framework ، کلید اصلی ، کلید خارجی و ایندکس ها و روابط بین جداول رو تعریف کنید مثلا من اینجا گفتم که مدل من اسکیماش Dynamic  هست و حالا سایر تنظیماتی که وجود داره ....

 این هم از Config خب میرسیم به فضای نام KS.Dynamic.DataAccess.DynamicDbContextsMigration ، خب من اومدم یه همچین  namespace ساختم و دو تا کلاس توش تعریف کردم ، اول Configuration من رو توضیح بدم .

 شما برای اینکه از Migration Entity Framework استفاده کنید حتما باید یک کلاسی از نوع DbMigrationsConfiguration  داشته باشید و context  تون رو بهش پاس  بدید ، اینجا Dynamic context .

و AutomaticMigrationsEnabled هم حتما false  کردم ، چون نمیخوام اتوماتیک Migration اتفاق بیفته ، میخوام کاملا دستی و در کنترل برنامه نویس باشه .

این تیکه کدی که شما اینجا میبینید میتونید از طریق این پایین ، Snippet code ها که یکیشون ایجاد کلاس ConfigurationMigration هست . همونطور که میبینید اینجا اول کامنت داره که چیا باید Reference بشن و تو این قسمت گفته باید fullname space qualified context name تون رو بذارید .

حالا من و میبینید که Dynamic context رو گذاشتم و اینجا هم باز میگه که باید fullname space qualified dbcontext name قرار داده بشه .

این کلاس configuration  حتما باید باشه تاmigration  رو بتونیم انجام بدیم .

خب class  بعدی که تو فضای نام DynamicDbContextMigration قرار داره DynamicMigration هست ، خب توی DynamicMigration میبینید که ما class  داریم به اسم  FirstTime که partial هم هست . و خب همون متد Up  و down  ، برای Migration های Entity Framework رو داره .

 خب این class  از کجا اومده ؟ این class به صورت اتوماتیک generate میشه و چجوری باید generate بشه اتوماتیک ؟

 من Dll  با نام DataAccess رو انتخاب میکنم و کامپایل با ساخت وابستگی ها رو میزنم و تو مدیریت خروجی ها و اینجا میبینم که R19  برای من compile شده .

از قسمت code generate ایتم با نام  Entity FrameWork Migration Generator رو من انتخاب میکنم و اینجا میبینید که ما سه تا عملیات میتونیم انجام بدیم ، ایجاد یک migration جدید ، اجرای یک migration و تولید اسکرییت  بین دو تا migration. 

من الان اون migration FirsTime رو میخوام بسازم یرای شما تا طریقه ش رو ببینید. نوع انتخاب ، connection پیش فرض رو انتخاب میکنم ، انتخاب نگارش ، خب همونطور که دیدید 19 رو من انتخاب میکنم ، انتخاب class از نوع DbMigration   ، این همون کلاس Configuration ایی هست که من گفتم با Snippet Code ساختیم و Context مون رو بهش دادیم.

انتخاب زبان سی شارپ (#C) و فضای نام ریشه اسمبلی KS.Dynamic.DataAccess  و نام Migration را می گم  FirstTime .

من اجرا رو میزنم ، همونطور که مشاهده میکنید الان برای من اون کدی که من به شما نشان دادم رو (FirstTime) رو برای من ساخته ... Create table و اینا... 

و این قسما پایین یک سری کدی ساخته شده که شما این ها رو هم باید کپی کنید و قرار بدید تو جای مناسبش

و این کدی هست که من paste  کردم و این قسمت پایین ش رو هم من رو در قسمتauto generator قرار دادم و اگر با این قسمت مقایسه ش کنید دقیقا میبینید که همین قسمت هم پایین قرار گرفته.

 بعد از این که این کار رو کردید شما باید یک بار دیگه Data Access رو compile کنید تا بتونید از سایر امکانات migration  مثل اجرای یک migration استفاده کنید .

 میام توی Entity FrameWork Generator .. میزنم ....اجرای یک Migration اینو فقط باید از روی کد DLL اجرا کنید .... توی اجرای migration  ارتباط پیش فرض و انتخاب class از نوع DbMigrationsConfiguration و ... 

خب میبینید که migration   رو برای ما اتوماتیک آورد و یک migration داریم ما میتونیم migration history  رو نگه داریم FirstTime… ...  بعد مثلا یک جدول اضافه کردیم اسم migration اش رو میذاریم مثلا" AddSeecondTable و اون migration جدیدتون هست . 

اولین migration  رو انتخاب میکنم و روی دکمه اجرا کلیک میکنم..... اینجا یک پیغامی میده راجع به Autofac.Integration.Mvc که این مهم نیست ، چون خواسته که اون متد Seed رو اجرا کنه نمیتونه چون ما از Dependency Injection استفاده کردیم امکان اجرای متد Seed رو نداره اما این معنیش اینه هر وقت این پیغام خطا رو داد درست کار کرده 

حالا اگر من برگردم این قسمتی که بخوام جداول خودم رو ببینم ، همانطور که دیدید ما قبلا" فقط  دو تا اسکیما contant management و  security داشتیم.

 من الان یکبار دیگه این کوئری خودم رو اجرا کنم، اینبار میبینید که اسکیماDynamic  هم برای ما اضافه شده، DynamicTestModel که اسم جدول مون بود و جدول migration history هم اضافه شده برای کنترل تاریخچه  migration ها 

شما به کمک Migration Entity Framework می تونید کلیه ساخت و تغییرات دیتابیس تون رو انجام بدید و تاریخچه این نغییرات رو هم برای حالت  undo کردن نگهداری کنید .