خوب اول از همه هدف چیه ؟ اینه که این دو تا رو به هم وصل کنیم مثلا میخوایم بر اساس id بیاد و نام catogery اون محصول رو بیایم از یه جدول دیگه به اسم category بریم بخونیم که خودش یه entity جداست و جدول جداگانه خوب برای این کار یه سری convention داریم که ef core اون ها رو شناسایی میتونه بکنه و ارتباط رو برقرار کنه

خوب اینجا همونطوری که مبینید ما در category اومدیم یه ICollection از نوع Product درست کردیم ، اینجا ef میفهمه که یه ارتباط یک به چند اینجا داریم هر relation یک به چند باید در طرف چند باید کلید خارجی داشته باشه حالا میخوایم کلید خارجی معرفی کنیم

برای تعریف کلید خارجی میتونیم از نام + Id استفاده کنیم

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

خوب یه سری اصطلاحات داریم اینجا : #Principal_Entity

این یعنی سر شاخه یا پدر و محصولات میشن child خوب مورد بعدی

اینجا product میشه dependent entity که یعنی این که به entity اصلی وابسته است.

خوب principal key میشه کلید اصلی شاخه پدر خوب مورد بعدی هم کلید خارجی هستش :

خوب مورد بعدی میشه navigation property

خوب مورد بعدی هم میشه :

خوب مورد بعدی self refrencing relationship هستش که یعنی جدول هایی که با خودشون ارتباط دارند که یعنی به صورت درختی بتونیم اطلاعات واردش کنیم یعنی در داخل یه entity خوده property ها با هم ارتباط دارن

خوب حالا اینجا میبینیم که ما به هر جفت entity ها دسترسی داریم ، اینجا اومدیم category رو تعریف کردیم و بعد همونطوری که میبینید به product هم دسترسی داریم ، این به این دلیل هستش که بالاتر ما اومدیم ICollection Product رو براش نوشتیم اگر ننوشته بودیم نمیشد ، ولی چون نوشتیم ارتباط دو طرف داریم

ShoppingSiteDbContext context = new ShoppingSiteDbContext();

این خط کد یک شیء جدید از کلاس ShoppingSiteDbContext ایجاد می‌کند. این کلاس به عنوان نماینده‌ای از پایگاه داده شما عمل می‌کند و شامل مجموعه‌هایی از جداول (یا موجودیت‌ها) و همچنین تنظیمات مربوط به پایگاه داده است. در اصل، DbContext مسئول مدیریت ارتباطات و عملیات بر روی پایگاه داده است.

context.Database.EnsureDeleted();

این متد بررسی می‌کند که آیا پایگاه داده‌ای با تنظیمات مشخص شده وجود دارد یا خیر. اگر وجود داشته باشد، آن را حذف می‌کند. این متد معمولاً برای اهداف توسعه و آزمایش استفاده می‌شود، به خصوص زمانی که می‌خواهید مطمئن شوید پایگاه داده‌ای که ایجاد می‌شود تازه است و هیچ داده‌ای از قبل در آن وجود ندارد.

context.Database.EnsureCreated();

پس از حذف پایگاه داده با EnsureDeleted، این متد اطمینان حاصل می‌کند که پایگاه داده با ساختار فعلی مدل داده شما ایجاد شود. این شامل ایجاد جداول، ستون‌ها، و روابط بین آنها است بر اساس تعریف مدل‌ها در DbContext.

خلاصه:

این دو خط کد به طور کلی برای راه‌اندازی مجدد پایگاه داده شما استفاده می‌شوند. ابتدا هر پایگاه داده‌ای که قبلاً وجود داشته باشد حذف می‌شود (EnsureDeleted)، سپس پایگاه داده جدیدی بر اساس مدل داده‌های فعلی شما ایجاد می‌شود (EnsureCreated). این رویکرد معمولاً در محیط‌های توسعه و آزمایش استفاده می‌شود تا مطمئن شوید که پایگاه داده شما همیشه با آخرین تغییرات مدل داده همگام است.

خوب حالا ما میدونیم که اگر بخوایم دو تا entity رو بهم وصل کنیم باید کلید خارجی داشته باشیم ، اینجا اومدیم کلید خارجی که تعریف کردیم رو کامنت کردیم و بعد ولی خوده دیتا بیس میاد با convention های خودش برامون درست میکنه :

اگر واقعا به دیتا های دو طرفه نیاز نداریم تعریفشون نکنیم چون میشن سر بار برنامه خوب حالا بیایم روش های دیگه رو هم برای درست کردن کلید خارجی ببینیم : توی این حالت پایین ما خودمون به جای این بخوایم اکتفا کنیم به ef که بیاد برامون relation رو درست کنه خودمون درستش میکنیم، اینطوری :

مدل بعدی:

خوب حالا فکر کنید که قانون گذاشتن که برای تعیین کلید خارجی اول نام اون پارامتر رو باید FK بزاریم

خوب حالا میخوایم توی حالاتی که navigation property نداریم این قضیه رو بررسی کنیم :

میایم اینطوری ازش استفاده میکنیم فقط دفت داشته باشیم که اونجا به has one یه T یا تایپ دادیم از نوع Category برای این که میخوایم این دو تا رو به هم وصل کنیم

خوب این نکته رو در نظر داشته باشید که ما میتونیم relation هایی که ایجاد میکنیم اختیاری یا اجباری باشه که در ادامه توضیح میدیم : توی قسمت بالا نمیتونیم وقتی که داریم محصولی رو اضافه میکنیم category بهش ندیم ، این یعنی این که همیشه باید product و category باید با هم داده بشن برای این که در دیتا بیس ذخیره شوند. خوب برای این که اختیاریش کنیم این قضیه رو میایم یه قابلیت nullable بودن رو به کلید خارجی مون میدیم ، اینطوری:

خوب حالا فکر کنید ما این کار رو کردیم ولی میخوایم باز هم در دیتا بیس بیایم بگیم که نه این قضیه اجباریه برای این کار میریم توی کانفیگ دیتابیس و اینطوری مینویسیم:

خوب حالا اینجا توی همون required هم میتونیم بهش دوباره false بدیم اینطوری میشه اختیاری و true بدیم میشه اجباری

خوب حالا میرسیم به مورد بعدی

خوب توی این شرایط دیگه convention های ef نمیتونه تشخصی بده که کدوم به کدوم وصله و ما باید بیایم خودمون این ها رو به هم وصل کنیم

حالا اینجا میخوایم این قضیه رو بررسی کنیم که مثلا یکی از category ها رو پاک کردیم و چند تا product بهش وصل بودن حالا چهه اتفاقی می افته و ما باید چی کار کنیم

توی این حالت یه کاری که میشه انجام داد این ها هستش که :

تعریف کنیم و تعیین کنیم که اگر این اتفاق انجام شد چه بلایی به سره child اش بیاد : خوب no action که هیچ کاری انجام نمیده و خودمون باید بیایم و دستی این کار رو انجام بدیم خوب حالا با set null : اگر relation که داریم optinal باشه میاد اتوماتیک set null رو انجام میده حالا cascade : توی این حالت زمانی که یه category رو پاک میکنیم تمام child هاش باهاش پاک میشن گزینه set default اینطوری میشه که میاد اون محصول هایی که categry شون پاک شده و assign میکنه یه category که ما به صورت default تعیین کردیم

خوب ما توی ef این 3 تا گزینه رو داریم

خوب حالا مثال :

خوب حالا میخوایم ببینیم که با این config چه داستانی پیش میاد :

وقتی که یه category رو پاک میکنیم تمام product های مرتبط به اون حذف میشن

خوب حالا میخوایم حالت no action رو در کد بنویسیم و تست کنیم که ببینیم وقتی که relation اجباری هستش چجوری میشه

خوب اینجا ارور میده و نمیشه :

توی این حالت برای پاک کردن category باید بریم تمام product هایی که بهش وصل هستند رو به یه category دیگه وصل کنیم که relation اجباری انجام بشه و بعد میتونیم category رو پاک کنیم یا این که کل product رو پاک کنه تا بتونه category رو پاک کنه

خوب حالا فرض کنیم که relation اختیاری هستش :

در این حالت همه چی اوکیه و پاک شدنش انجام میشه :

و توی دیتابیس catgory رو null میکنه

حالا دوباره فرض کنیم که relation اجباریه : خوب مورد بعدی setnull هستش که اینطوری به ارور میخوریم

چون میگه که اون فیلدی که میخوای setnull کنی اجباریه و توی این شرایط نمیشه دیتابیس ساخت و نکته ای که هست اینه که set null رو فقط میتونیم روی property هایی که optinal هستند اعمال کنیم

یعنی با علامت سوال nullable شدن مورد بعدی آپشن خوده ef هستش

اینجا داره میگه که اکشن وقتی انجام شد خوده دیتا بیس بره اون رو handle کنه که چه اتفاقی بیوفته

خوب میرسیم به مورد بعدی :

وقتی که داریم از client set null استفاده میکنیم یعنی داریم از database engine میخوایم که این کار رو انجام بده

خوب خیلی خیلی مهم : Ef فقط زمانی میتونه اون دستوراتی که بهش مرتبط هست رو اجرا کنه در دیتابیس که اون اطلاعاتی که داخل دیتابیس ریخته شده در خوده برنامه تولید شده باش و ef هم در برنامه به اونها دسترسی داره و میتونه روشون تغییر ایجاد کنه

فکر کنید که اینجا اومدیم و کد هایی که مربوط به پر کردن اطلاعات دیتا بیس هستش رو پاک کردیم و بعد اومدیم از دستور remove که برای خوده efcore هستش برای پاک کردن اطلاعات داخل دیتابیس استفاده کردیم — ولی این کار باعث ارور میشه و انجام نمیشه چون ef به اون اطلاعات دسترسی نداره حالا برای رفع این اشکال باید چی کار کنیم ؟ باید بیایم اطلاعات رو اول از دیتابیس بگیریم و بعد بریزیمش توی یه لیست و بعد بیایم روش کاری رو که میخوایم اعمال کنیم

این قضیه هم میتونه خوب باشه و هم بد در جاهایی که نیازه بدونیم که دقیقا چه child ای رو میخوایم null کنیم بهتره که از ef استفاده کنیم ولی جاهایی که این نیاز نیست بهتره که از client set null استفاده کنیم

ارتباط یک به یک : مثلا یک عکس از محصول به یک محصول متصله :

خوب دقت کنید که هر دو سره product و productimage کلید هستش و ارتباط یک به یک هستش

خوب حالا دوباره فرض کنید که بریم اسم کلید خارجی رو تغییر بدیم

در این حالت باید بریم براش کانفیگ بنویسیم

میخوایم ارتباط product رو با tag تعریف کنیم که یه product میتونه چند تا تگ داشته باشه و همچنین هر تگی میتونه برای چندین تا product ثبت بشه

توی ef core ارتباط چند به چند نداریم باید 2 ارتباط یک به چند داشته باشیم با ساختن یک entity با جدول میانی

خوب این entity که داریم نیازی به کلید اصلی نداره و از اسمش هم پیداست که میخواد product و tag رو به هم بچسبونه

خوب اینجا به صورت اتوماتیک تشخیص میده که این دو تا به هم وصل هستند

چند تا نکته هست که باید رعایت کنیم :

خوب حالا میخوایم کلید اصلی رو تعیین کنیم

اینطوری میایم هم product id و هم tag id رو به عنوان کلید اصلی در نظر میگیریم - این باید خاطرمون باشه که هردوی این ها برای هر product یکتا هستش / یعنی یه یک product نمیایم دو بار یک نوع تگ بدیم

خوب توی دیاگرام هم همونطوری که میبینیم یک ارتباط یک به چند از product tags به products و یک ارتباط یک به چند از product tags به tags

و در نهایت این رو میشه گفت که یک ارتباط چند به چند بین product و tags انجام شده