فصل 7 از 24 درس 1 از 1

Relationships در Entity Framework Core

Relationships در Entity Framework Core

بخشی از آموزش جامع ASP.NET Core Web API با .NET 10

محتوای درس 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، امنیت و نیازهای نگهداری پروژه هماهنگ بماند.