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ể StudentCourse. 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ể StudentCourse.

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 StudentsCourses - đó là Student_StudentIdCourse_CourseId như hình dưới đây.

one-to-one relationship in code first

Lưu ý: EF tự động tạo bảng tham gia với tên của cả hai thực thể và hậu tố 's'.

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()WithMany() được sử dụng để cấu hình mối quan hệ nhiều-nhiều giữa các thực thể StudentCourse.

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:

one-to-one relationship in code first

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ó.