[英]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.