EF Code-First - Cấu hình mối quan hệ nhiều-nhiều
Cấu hình mối quan hệ nhiều-nhiều trong Entity Framework
Ở phần này, chúng ta sẽ tìm hiểu cách cấu hình mối quan hệ nhiều-nhiều giữa các lớp thực thể Student
và Course
. Một sinh viên có thể tham gia nhiều khóa học và một khóa học có nhiều sinh viên.
Cấu hình mối quan hệ nhiều-nhiều bằng cách tuân theo quy ước mặc định của Code First
EF 6 có các quy ước mặc định cho mối quan hệ nhiều-nhiều. Bạn cần có một thuộc tính điều hướng kiểu tập hợp ở cả hai đầu.
Ví dụ, lớp Student
có thuộc tính điều hướng kiểu ICollection<Course>
và lớp Course
có thuộc tính điều hướng kiểu ICollection<Student>
để tạo mối quan hệ nhiều-nhiều giữa chúng mà không cần bất kỳ cấu hình nào, như được trình bày bên dưới:
public class Student
{
public Student()
{
this.Courses = new HashSet<Course>();
}
public int StudentId { get; set; }
[Required]
public string StudentName { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
public class Course
{
public Course()
{
this.Students = new HashSet<Student>();
}
public int CourseId { get; set; }
public string CourseName { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
Sau đây là lớp Context bao gồm các thực thể Student
và Course
.
public class SchoolDBContext : DBContext
{
public SchoolDBContext() : base("SchoolDB-DataAnnotations")
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
EF API sẽ tạo ra ba bảng là Students
, Courses
và bảng tham gia tên là StudentCourses
trong cơ sở dữ liệu. Bảng StudentCourses
sẽ bao gồm khóa chính của cả hai bảng Students
và Courses
- đó là Student_StudentId
và Course_CourseId
như hình dưới đây.
Cấu hình mối quan hệ nhiều-nhiều bằng Fluent API
Như bạn đã thấy ở trên, các quy ước mặc định của Code First cho mối quan hệ nhiều-nhiều sẽ tạo ra bảng tham gia với các quy ước đặt tên mặc định.
Sử dụng Fluent API để tùy chỉnh tên bảng và tên cột tham gia, như được trình bày bên dưới:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>()
.HasMany<Course>(s => s.Courses)
.WithMany(c => c.Students)
.Map(cs =>
{
cs.MapLeftKey("StudentRefId");
cs.MapRightKey("CourseRefId");
cs.ToTable("StudentCourse");
});
}
Trong ví dụ trên, các phương thức HasMany()
và WithMany()
được sử dụng để cấu hình mối quan hệ nhiều-nhiều giữa các thực thể Student
và Course
.
Phương thức Map()
nhận tham số kiểu delegate Action, do đó chúng ta có thể truyền các biểu thức lambda để tùy chỉnh tên cột trong bảng tham gia.
Chúng ta có thể chỉ định tên thuộc tính khóa chính của bảng Student
trong phương thức MapLeftKey()
(chúng ta đã bắt đầu với thực thể Student
, vì vậy nó sẽ là bảng bên trái) và khóa chính của bảng Course
trong phương thức MapRightKey()
.
Phương thức ToTable()
chỉ định tên của bảng tham gia (trong trường hợp này là StudentCourse
).
Đoạn mã trên sẽ tạo bảng tham gia StudentCourse
với hai khóa chính là StudentRefId
, CourseRefId
và chúng cũng sẽ là khóa ngoại, như được hiển thị bên dưới:
Theo cách này, bạn có thể ghi đè các quy ước mặc định của Code First cho mối quan hệ nhiều-nhiều và tùy chỉnh tên bảng tham gia và các cột của nó.