آرزو باقری
آرزو باقری
خواندن ۴ دقیقه·۸ ماه پیش

بررسی Value Object Using Complex Type

در EF 8 ویژگی هایی اضافه شده است که می خواهیم به Value object using complex type بپردازیم. انواع مختلفی از داده ها ممکن توی Data base نگهداری بشن :

1) داده های ساده

2) داده های چند مقداری با کلید

3) داده های چند مقداری بدون کلید

1) داده های ساده : مثلا یه Entity داریم ، یه سری اطلاعات ساده داخلش هست : نام ، نام خانوادگی ، تاریخ تولد و یه سری Primitive type وجود داره که به ازاش توی DB هم نوعی وجود داره و اینا میتونن به هم مپ بشن و هر کدوم از این داده ها به عنوان یک Column در جدول ما در نظر گرفته میشن.

2) داده های چند مقداری با کلید : مثلا Order رو در نظر بگیرید با OrderLine ، خب OrderLine نگهداری میکنه که چه محصولی ، چه تعدادی و با چه قیمتی خریداری شده؟ ولی غیر از اینکه این داده ها رو نگه میداره یه شناسه هم میتونه داشته باشه ، یعنی OrderLine میتونه شناسه داشته باشه برای خودش و به عنوان یک جدول تو DB تعریف بشه و پراپرتی هایی هم که داره به عنوان فیلد های اون جدول در نظر گرفته میشن.

3) داده های چند مقداری بدون کلید : یه سری دیگه داده داریم که مثل همین OrderLine چند مقداری هستن ولی شناسه پذیر نیستن، شناسه خاصی ندارن ، خودشون ویژگی هستن از یک Entity و اگر مقدارشون تغییر کنه، ماهیت شون عوض میشه. مثل رنگ RGB داره، وقتی در مورد رنگ صحبت می کنیم ، اگر هر کدوم از مقادیر RGB تغییر کنه ، دیگه رنگ، رنگ قبلی نیست، تغییر میکنه یا مثلا وقتی در مورد فردی صحبت می کنیم یه نفر ممکن اسمش عوض بشه ولی همون آدم قبلیه، یه نفر دائما سنش داره تغییر میکنه ولی همون آدم قبلیه ولی رنگی که RGBش تغییر بکنه رنگ قبلی نیست.به این داده ها میگیم Value Object ، داده هایی که با مقدارشون شناسایی میشن ، شناسه خاصی ندارن ، تغییر در آنها باعث تغییر در کل فرآیندشون میشه. همچین داده هایی رو در نسخه های قبلی EF به شکل های مختلفی نگهداری می کردیم. بعضی وقت ها به صورت Owned Type ازشون استفاده می کردیم ، یه وقت هایی خودشونو تبدیل میکردیم به یه Entity ، یعنی با اینکه Value Object بودن و با Value شون شناسایی میشدن ، یه شناسه ای از طرف خودمون بهش میدادیم صرفا بابت اینکه بتونیم جدولی بهشون تخصیص بدیم و شناسه شونو جاهای مختلف استفاده کنیم. یعنی Value Object رو تبدیل می کردیم به یه Entity . اینا راه کارهایی بود که ما تا قبل از این داشتیم اما در انتیتی فریم ورک هشت ، Complex Type ها اضافه شدن و می تونیم از Complex Type ها هم استفاده کنیم. به چه شکلی؟

مثال : مثلا یه کلاس Person داریم با یه کلاس PhoneNumber :

public class Person { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public PhoneNumber Home { get; set; } public PhoneNumber Work { get; set; } } public class PhoneNumber { public string CountryCode { get; set; } public string Phone { get; set; } }

که از کلاس PhoneNumber در کلاس Person استفاده کردیم. حالا اگه اینو Add Migration کنیم خطا میده که نمیتونیم Db Context رو ازش Instance بسازیم چون یه انتیتی PhoneNumber داریم که Primary Key نداره ، همونطور که میدونیم دفعه اول که میخواد Instance ساخته بشه Model رو Db Context می سازه ، میره تمام رفرنس Type هایی که وجود داره ، به عنوان انتیتی در نظر میگیره و دونه دونه مپ شون میکنه. یکی از ویژگی هایی هم که انتیتی باید داشته باشه که پذیرفته بشه از طرف Db Context ، داشتن شناسه است. کلاس PhoneNumber شناسه نداره و داره به ما خطا میده. حالا تکلیف چیه؟

تکلیف اینه که ما براش شناسه بزاریم، اما چجوری این کار و کنیم؟ میاییم Id میزاریم؟ نه، نمیخواییم شناسه داشته باشه، PhoneNumber من اگه شماره عوض بشه Entity کلا عوض میشه، کل ارزش اون Data از بین رفته ، دیگه Data قبلی نیست ، نمیخوام بهش Id بدم که مقدارش بخواد عوض بشه ، میخوام تبدیلش کنم به Value Object ، میام از Complex Type استفاده میکنم :

[ComplexType] public class PhoneNumber { public string CountryCode { get; set; } public string Phone { get; set; } }

حالا PhoneNumber رو به عنوان Value Object شناسایی میکنه. اگه این بار Migration بزنیم ، DB رو ایجاد کرده و به ازای هر کدوم فیلدهاشونو ایجاد کرده و مثل فیلدهای عادی میتونیم ازش استفاده کنیم. اما نکته ای که هست ما از کلاس PhoneNumber داریم استفاده می کنیم برای نگهداری Value Object ها، یعنی کلاسم قابل تغییره و وقتی کلاسم که یه Value Object هست ، جاهای مختلف استفاده بشه و تغییر بکنه ، کل رفرنس های اون کلاس تغییر میکنه ، باید کلاس مونو Immutable کنیم ، یعنی مثل Value Object که توی DDD تعریف می کنیم یا میاییم Private می کنیم و متد بنویسیم برای تغییرش ، یا اینکه اصلا اینجا میگیم :

[ComplexType] public record PhoneNumber(string countryCode , string phone);

اینا راه کارهایی هستن که برامون وجود داره و از این به بعد دیگه Immutable بودن رو خود دات نت برامون رعایت میکنه.






value objectcomplex typeبرنامه نویسیانتیتی فریم ورک 8سی شارپ ۱۲
علاقه مند به مهندسی نرم افزار
شاید از این پست‌ها خوشتان بیاید