簡體   English   中英

沒有鏈接表/模型的多對多關系?

[英]Many-to-many relationships without link tables/models?

我正在創建一個 ASP.NET Web API 項目(首先是數據庫),它從 MSSQL 數據庫中提取數據(只讀訪問)。 數據庫有幾個表,但沒有主/副鍵(我們不能改變它)。 我已經建立了一對多的關系,沒有任何問題,但是當涉及到多對多時,我不得不使用鏈接表來保存雙方的密鑰。

public class Student
{
    public int StudentId { get; set; }
    public string Name { get; set; }

    public IList<StudentCourse> StudentCourses { get; set; }
}

public class Course
{
    public int CourseId { get; set; }
    public string CourseName { get; set; }
    public string Description { get; set; }

    public IList<StudentCourse> StudentCourses { get; set; }
}

鏈接表:

public class StudentCourse
{
    public int StudentId { get; set; }
    public Student Student { get; set; }

    public int CourseId { get; set; }
    public Course Course { get; set; }
}

因為數據庫中不存在鏈接表,所以我收到“Data.SqlClient.SqlException: 'Invalid object name 'StudentCourse'”錯誤。

public class SchoolContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=.\\SQLEXPRESS;Database=EFCore-SchoolDB;Trusted_Connection=True");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<StudentCourse>().HasKey(sc => new { sc.StudentId, sc.CourseId });
    }
    
    public DbSet<Student> Students { get; set; }
    public DbSet<Course> Courses { get; set; }
    public DbSet<StudentCourse> StudentCourses { get; set; }

關系:

modelBuilder.Entity<StudentCourse>().HasKey(sc => new { sc.SId, sc.CId });

modelBuilder.Entity<StudentCourse>()
    .HasOne<Student>(sc => sc.Student)
    .WithMany(s => s.StudentCourses)
    .HasForeignKey(sc => sc.SId);


modelBuilder.Entity<StudentCourse>()
    .HasOne<Course>(sc => sc.Course)
    .WithMany(s => s.StudentCourses)
    .HasForeignKey(sc => sc.CId);

我考慮過在這些鍵上連接表,但它似乎不是處理關系和獲取相關記錄的有效方法。 你會建議什么解決方法?

實體框架是一個對象到關系的映射器,映射器是這里的關鍵術語。 為了在要映射的對象之間建立關系,關系數據庫中的這些實體之間必須存在關系。

這樣想一下,如果學生和課程之間存在關系,那么這種關系在您的數據庫中是如何表示的? 如果我讓您針對該數據庫編寫兩個 SQL 查詢,您將如何返回以下數據?

  • 列出特定課程的所有學生。
  • 列出特定學生的所有課程。

你不能只用一個課程和一個學生表來做到這一點。 如果沒有鏈接表,那么您要么以一種方式或另一種方式擁有一對多關系,要么數據庫以非關系方式處理它。 (例如 Student 包含一個帶有逗號分隔的課程 ID 列表的字符串字段)在這種情況下,EF 將無濟於事。

如果數據庫不支持記錄學生和他們的課程之間的映射,您可以在其中查詢一個學生如何參加多門課程,而每門課程可以有多名學生參加,那么 EF 無法配置為以某種方式自動神奇地讀取和持久化此類一種關系。 數據庫中必須存在多對多表,否則這種關系不存在。 使用 EF6 和 EF Core 5+,您可能會讀到 EF 可以在沒有鏈接實體的情況下處理多對多關系,這是真的,但這並不意味着沒有鏈接 該表必須存在,但您不需要定義 StudentCourse(或 CourseStudent)實體。

代替:

public IList<StudentCourse> StudentCourses { get; set; }

在學生和課程中,學生可以擁有:

public IList<Course> Courses { get; set; }

而課程有:

public IList<Student> Students { get; set; }

這仍然通過鏈接表進行映射,並且如果該關系僅由表中的 StudentId 和 CourseId 組成,沒有其他需要映射/配置的列,EF 可以完全在幕后管理該關系和表。

如果有一個鏈接表,只是沒有按照您的期望命名:您可以隨意調用實體,並通過屬性、 DbContext.OnModelCreating(ModelBuilder)EntityTypeConfiguration使用配置將該實體和屬性映射到現有表和列,但它們可能會被命名。 但是必須存在這樣一個表來支持這種關系。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM