【问题标题】:Entity Framework Code First navigation property through relational table通过关系表的实体框架代码优先导航属性
【发布时间】:2016-10-19 15:30:25
【问题描述】:

我正在尝试使用一些 Entity Framework Code First 模型设置一些导航属性。我希望它们看起来像这个例子:

public class Course
{
    [Key]
    public int CourseId { get; set; }
    public string CourseName { get; set; }
    public virtual ICollection<Student> Students { get; set; }
}

public class Student
{
    [Key]
    public int StudentId { get; set; }
    public string StudentName { get; set; }
    public virtual ICollection<Course> Courses { get; set; }
}

public class StudentCourses
{
    [Key, Column(Order = 0)]
    public int StudentId { get; set; }
    public virtual Student Student { get; set; }
    [Key, Column(Order = 1)]
    public int CourseId { get; set; }
    public virtual Course Course { get; set; }
}

因此,StudentCourses 表中将建立 Student 和 Course 关系。学生类的实例将自动引用所有学生的课程,反之亦然,课程类的实例将自动引用其所有学生。 StudentCourses 类的一个实例会自动引用它的 Student 和 Course。但是当我尝试更新数据库时,这些关系似乎没有得到正确解释。我在这里有什么遗漏吗?也许需要在上下文类中进行一些配置?导航属性的大多数示例仅显示一对多关系导航属性。

【问题讨论】:

    标签: c# asp.net entity-framework ef-code-first code-first


    【解决方案1】:

    当您有M : M 关系时,您需要按如下所示构建模型。您不需要构建联结表。 EF 会在您进行数据迁移时为您创建一个。

    使用约定的模型配置。

    public class Student
    {
        public Student() 
        {
            this.Courses = new HashSet<Course>();
        }
    
        public int StudentId { get; set; }
    
        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; }
    }
    

    你的上下文类应该是这样的。

    public class YourDBContext : DBContext
    {
        public YourDBContext () : base("Default")
        {
        }
    
        public DbSet<Student> Students { get; set; }
    
        public DbSet<Course> Courses { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }
    

    【讨论】:

    • 啊,所以 EF 从模型中完全抽象出该表。我认为我需要为 EF 创建的联结表创建一个类,但我认为导航属性不需要这样做。
    • 是的,EF会为你创建一个联结表。你不需要手动做。
    【解决方案2】:

    在听从 Sampath 的建议后,我实际上决定要为关系附加一些其他属性。所以我最终像这样定义了 StudentCourses 类:

    public class StudentCourses
    {
        [Key, Column(Order = 0)]
        public int StudentId { get; set; }
        public virtual Student Student { get; set; }
        [Key, Column(Order = 1)]
        public int CourseId { get; set; }
        public virtual Course Course { get; set; }
        public int Grade { get; set; }
    }
    

    所以我像这样更改了学生和课程:

    public class Course
    {
        [Key]
        public int CourseId { get; set; }
        public string CourseName { get; set; }
        public virtual ICollection<StudentCourses> Students { get; set; }
    }
    
    public class Student
    {
        [Key]
        public int StudentId { get; set; }
        public string StudentName { get; set; }
        public virtual ICollection<StudentCourses> Courses { get; set; }
    }
    

    最重要的是,我没有将 StudentCourses 添加到 DbContext。所以在 Update-Database 执行后,EF 自动为 StudentCourses 创建了表,并且导航属性都可以正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      相关资源
      最近更新 更多