تمام ORM ها از جمله Entity framework Core به ازای کلاس هایی که در domain class شما هستند، جداولی را در پایگاه داده رابطه ای ایجاد می کنند. شما می توانید model Domain خود را با استفاده از Inheritance طراحی کنید. در برنامه نویسی شی گرا ما روابط has a و is a داریم. درحالیکه در پایگاه داده رابطه ای مبتنی بر SQL ما تنها رابطه has a داریم و رابطه is a نداریم. بنابراین چطور می توان Domain model های Object Oriented را به جداول پایگاه داده ی رابطه ای نگاشت کرد؟
برای برطرف کردن گپ بین Object Oriented و پایگاه داده ی رابطه ای ORM ها چندین Pattern دارند. Entity Framework Core نیز الگویی به نام TPH (Table-Per-Hierarchy) برای حل این مشکل دارد.
TPH (Table-Per-Hierarchy)
این رویکرد یک جدول برای کل سلسله مراتب کلاس ها درنظر می گیرد که نام کلاس پایه (Base Class) را می گیرد. این جدول شامل یک ستون Discriminator (تفکیک کننده) است که بین این کلاس ها تمایز قائل می شود. EF Core فقط کلاس هایی را شامل می شود که صریحاً در مدل گنجانده شده اند.
مدل زیر را درنظر بگیرید:
این مدل به شکل زیر در پایگاه داده SQL Server نگاشت می شود. توجه داشته باشید که ستون Discriminator به طورت ضمنی ایجاد شده است که نوع Blog ذخیره شده در هر سطر را مشخص می کند.
ستون های پایگاه داده در صورت استفاده از رویکرد TPH بطور خودکار Null قرار می گیرند. به عنوان مثال ، ستون RssUrl به صورت اتوماتیک Nullable است زیرا نمونه های وبلاگ معمولی این ویژگی را ندارند.
اگر شما نمی خواهید به ازای تک تک Entity ها در Model خود یک پراپرتی از نوع <>DbSet در کلاس Context خود تعریف کنید، می توانید از API Fluent استفاده کنید تا اطمینان حاصل کنید که همه این کلاس ها در Model گنجانده شده اند.
مدل زیر را در نظر بگیرید. این یک مدل خیلی ساده است که شامل یک کلاس abstract به نام Person و دو کلاس non-abstract به نام های Student و Teacher است. کلاس های Teacher و Student از کلاس Person ارث بری می کنند.
اگر به قرارداد پیش فرض EF Core متکی نیستید، می توانید Base type را صراحتا با استفاده از پراپرتی HasBaseType مشخص کنید.
جدول ایجاد شده به ازای این مدل در دیتابیس به شکل زیر خواهد بود:
علاوه براین، می توانید یک نام و نوع برای ستون Discriminator و مقادیری برای نشان دادن هر نوع Entity تعیین کنید:
در این مثال، نوع داده برای ستون Discriminator از نوع int تعریف شده و به نام PersonType نامگذاری شده است. جدول ایجاد شده در دیتابیس به شکل زیر خواهد بود.
اگر قصد دارید که مقادیر خودتان را برای ستون Discriminator ارائه دهید، باید مقادیری را برای همه Entity های غیر abstract در سلسله مراتب وراثت مشخص کنید. در این مثال کلاس Person چون به صورت abstract تعریف شده است، گنجانده نشده است. اما اگر base type به صورت abstract تعریف نشده باشد، باید یک مقدار متمایزکننده برای آن نیز درنظر بگیرید.