در آموزش پیادهسازی روابط چند به چند در EF Core، ابتدا مفهوم روابط چند به چند در پایگاه داده بررسی میشود. سپس نحوه پیادهسازی آن در EF Core با استفاده از جدول واسط (Join Table) و کلیدهای ترکیبی را یاد میگیریم. رابطه چند به چند یکی از انواع ارتباطات در مدلسازی دادههاست که زمانی اتفاق میافتد که دو موجودیت به گونهای به هم مرتبط شوند که هر نمونه از موجودیت اول میتواند با چندین نمونه از موجودیت دوم ارتباط داشته باشد و بالعکس.
به عنوان مثال، در یک سیستم مدیریت آموزشی، یک دانشجو میتواند در چندین دوره ثبتنام کند و هر دوره نیز میتواند شامل چندین دانشجو باشد. این نوع رابطه معمولاً با استفاده از یک جدول واسط (Join Table) پیادهسازی میشود که نقش پل بین دو جدول اصلی را ایفا میکند و شامل کلیدهای خارجی مرتبط با هر دو جدول است. این جدول واسط امکان مدیریت ارتباطات پیچیده را فراهم میکند و به صورت خودکار یا دستی در پایگاه داده طراحی میشود.
رابطه چند به چند (Many-to-Many) نوعی ارتباط بین دو موجودیت است که در آن هر نمونه از یک موجودیت میتواند با چندین نمونه از موجودیت دیگر مرتبط باشد و برعکس. برای پیادهسازی این رابطه، معمولاً از یک جدول واسط استفاده میشود.
ارتباط چند به چند (Many-to-Many) زمانی استفاده میشود که بین دو موجودیت (Entity) رابطهای وجود داشته باشد که هر نمونه از یک موجودیت میتواند با چندین نمونه از موجودیت دیگر مرتبط باشد و برعکس.
public class Student
{
public int Id { get; set; }
public required string Name { get; set; }
public required string Family { get; set; }
public required string Email { get; set; }
public ICollection<StudentCourse>? StudentCourses { get; set; }
}
public class Course
{
public int Id { get; set; }
public required string Name { get; set; }
public required int Credits { get; set; }
public ICollection<StudentCourse> StudentCourses { get; set; }= [];
}
public class StudentCourse
{
public int StudentId { get; set; }
public int CourseId { get; set; }
public required Student Student { get; set; }
public required Course Course { get; set; }
}
public class StudentViewModel
{
public int Id { get; set; }
public required string Name { get; set; }
public required string Family { get; set; }
public required string Email { get; set; }
}
public class CourseViewModel
{
public int Id { get; set; }
public required string Name { get; set; }
public required int Credits { get; set; }
}
public DbSet<Student> students { get; set; }
public DbSet<Course> courses { get; set; }
public DbSet<StudentCourse> StudentCourses { get; set; }
//--------------------------------------
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//--------------------------------------
modelBuilder.Entity<StudentCourse>()
.HasKey(sc => new { sc.StudentId, sc.CourseId });
//--------------------------------------
modelBuilder.Entity<StudentCourse>()
.HasOne(s => s.Student)
.WithMany(s => s.StudentCourses)
.HasForeignKey(s => s.StudentId)
.OnDelete(DeleteBehavior.Cascade);
//--------------------------------------
modelBuilder.Entity<StudentCourse>()
.HasOne(s => s.Course)
.WithMany(s => s.StudentCourses)
.HasForeignKey(s => s.CourseId)
.OnDelete(DeleteBehavior.Cascade);
}
CreateMap<Student,StudentViewModel>().ReverseMap();
CreateMap<Course, CourseViewModel>().ReverseMap();