Relationships در Entity Framework Core
Relationships در Entity Framework Core
محتوای درس Relationships در Entity Framework Core
.NET 10 | One-to-Many، One-to-One و Many-to-Many
Relationship در EF Core ارتباط میان Entityها را در مدل شیءگرا و Constraintهای دیتابیس همزمان بیان میکند. Foreign Key و Navigation Property نقش متفاوتی دارند و رفتار حذف باید آگاهانه انتخاب شود.
این فصل با تمرکز بر قراردادهای قابل اتکا، مرزبندی مسئولیتها و رفتار قابل پیشبینی در محیط واقعی تنظیم شده است. مثالها بر پایه ASP.NET Core و .NET 10 نوشته شدهاند.
1. چارچوب موضوع و مفاهیم اصلی
Relationship در EF Core ارتباط میان Entityها را در مدل شیءگرا و Constraintهای دیتابیس همزمان بیان میکند. Foreign Key و Navigation Property نقش متفاوتی دارند و رفتار حذف باید آگاهانه انتخاب شود.
واژگان و قراردادهای این بخش باید در سراسر پروژه یکدست بمانند؛ تفاوت میان لایه HTTP، منطق برنامه و زیرساخت زمانی روشن میماند که مسئولیت هر جزء بهصورت صریح تعریف شود.
| مفهوم | کارکرد |
|---|---|
| Principal | سمت مرجع رابطه |
| Dependent | سمت دارای Foreign Key |
| Navigation | ارجاع شیءگرا |
| Foreign Key | کلید ذخیرهشده |
| Cascade Delete | حذف وابسته |
| Junction Entity | واسط Many-to-Many |
2. ساختار پیشنهادی در پروژه
مدل Product میتواند CategoryId و Navigation به Category داشته باشد. Fluent API برای Constraint، DeleteBehavior و رابطههای پیچیدهتر خوانایی و کنترل بیشتری فراهم میکند.
public sealed class Product
{
public int Id { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; } = null!;
}
modelBuilder.Entity<Product>()
.HasOne(p => p.Category)
.WithMany(c => c.Products)
.HasForeignKey(p => p.CategoryId)
.OnDelete(DeleteBehavior.Restrict);3. سناریوی اجرایی
برای Product و Tag، اگر رابطه خودش دادهای نداشته باشد Many-to-Many مستقیم قابل استفاده است. اگر Relation دارای CreatedAt یا SortOrder باشد، Entity واسط صریح طراحی میشود.
در این سناریو، قرارداد ورودی و خروجی، مسیر شکست و رفتار قابل مشاهده سرویس باید پیش از جزئیات پیادهسازی مشخص شود. این رویکرد باعث میشود تغییرات بعدی بدون وابستگی پنهان و با امکان تست دقیق انجام شوند.
public sealed class ProductTag
{
public int ProductId { get; set; }
public int TagId { get; set; }
public DateTime CreatedAt { get; set; }
}
modelBuilder.Entity<ProductTag>()
.HasKey(x => new { x.ProductId, x.TagId });4. اصول طراحی و نگهداری
پیادهسازی قابل نگهداری تنها به درست کار کردن در مسیر موفق محدود نیست. مرزهای مسئولیت، قابلیت مشاهده، امنیت، رفتار در خطا و امکان توسعه تدریجی باید همزمان بررسی شوند.
- DeleteBehavior بر اساس مالکیت واقعی داده انتخاب شود.
- Navigationها برای Serialization مستقیم Entity به Client استفاده نشوند.
- Foreign Keyهای پرتکرار معمولاً به Index نیاز دارند.
- Optional/Required بودن رابطه با NULLability هماهنگ شود.
5. خطاهای رایج و کنترل آنها
بخش مهمی از کیفیت یک API در نحوه جلوگیری از خطاهای تکرارشونده مشخص میشود. موارد زیر باید در بازبینی کد و تستهای قبل از انتشار کنترل شوند.
- Cascade Delete گسترده بدون تحلیل Domain.
- Loop در Serialization به دلیل Navigationهای دوطرفه.
- نداشتن Key ترکیبی در Junction و ایجاد Duplicate.
- بارگذاری ناخواسته Collectionهای بزرگ.
6. چکلیست نهایی فصل
- Cardinality هر رابطه مشخص است.
- Foreign Key و Navigation صحیح تعریف شدهاند.
- DeleteBehavior بازبینی شده است.
- Migration Constraintهای مورد انتظار را ایجاد میکند.
7. جمعبندی
مفاهیم این فصل زمانی کامل محسوب میشوند که هم مسیر موفق و هم مسیر خطا قابل پیشبینی، قابل تست و قابل مشاهده باشند. طراحی نهایی باید با Contract API، امنیت و نیازهای نگهداری پروژه هماهنگ بماند.