【问题标题】:Many to Many Relationship EF Code First多对多关系 EF 代码优先
【发布时间】:2014-11-07 16:59:21
【问题描述】:

我开始学习 MVC,并尝试使用实体框架代码优先方法创建数据库。我有一个学生表和一个科目表,每个学生可以有多个科目,一个科目可以有多个学生。链接器表有一个成绩列,因为每个学生对每个科目都有不同的成绩。我在尝试创建数据库时遇到错误,告诉我在模型生成期间检测到一个或多个验证错误。这是我的模型。

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

}

public class Student
{
     [Key]
    public int StudentId { get; set; }
    public string Name { get; set; }
    public List<Course> Courses { get; set; }
}

public class StudentCourses
{
     [Key]
    public Course Course { get; set; }
     [Key]
    public Student Student { get; set; }
    public double Grade { get; set; }
}

public class CourseDb: DbContext
{

    public DbSet<Course> Courses { get; set; }
    public DbSet<Student> Students { get; set; }
    public DbSet<StudentCourses> StudentCourses { get; set; }


}

我搜索了一下,看到了一些处理多对多关系的方法,但没有一个在链接器表中有额外的属性(Grade 属性)。

【问题讨论】:

  • 请不要将 MVC 与实体框架混淆。它们是两种独立的技术。

标签: entity-framework ef-code-first


【解决方案1】:

不幸的是,如果您使用具有附加属性的中间表(或者实际上,如果您定义一个特定的类来管理该关系而不是让 EF 自动处理它),您将失去拥有直接导航属性的能力。

您必须将模型更改为:

public class Course
{
    ...

    public List<StudentCourses> Students { get; set; }
}

public class Student
{
    ...

    public List<StudentCourses> Courses { get; set; }
}

然后,例如,如果您要遍历特定学生的课程列表:

@foreach (var course in student.Courses)
{
    @course.Course.CourseName, @course.Grade
}

另外,值得一提的是,这可能会导致 1+N 次查询,因此如果您打算这样做,您应该在查询学生时急切地加载课程:

var student = db.Students.Include('Courses.Course').SingleOrDefault(m => m.StudentId == id);

编辑

您实际上在这里遇到了多个问题。我抓住了第一个,就停在那里,没有注意可能还有什么问题。您仍然会遇到错误,因为您在中间表上使用了复合键(学生和课程外键的组合)。这很好,但是当你指定多个键时,你还必须指定列顺序:

[Key, Column(Order = 0)]
public Course Course { get; set; }

[Key, Column(Order = 1)]
public Student Student { get; set; }

我也不确定您是否可以将Key 与导航属性一起使用。从来没有尝试过自己做,但它可能会奏效。如果仍然出现错误,我会尝试显式外键属性:

[Key, Column(Order = 0)]
public int CourseId { get; set; }
public Course Course { get; set; }

[Key, Column(Order = 1)]
public int StudentId { get; set; }
public Student Student { get; set; }

【讨论】:

  • 嗨,你的意思是我应该让实体框架自己制作链接器表,而不是尝试为它创建一个类?我已经按照您告诉我的方式更改了课程,但仍然遇到相同的错误?感谢您的帮助!
  • 不一定。特别是如果您需要有关关系的额外数据 (Grade),实际上您不能让 Entity Framework 为您处理。
  • 成功了!感谢您抽出时间来提供帮助!非常感谢
猜你喜欢
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-16
  • 1970-01-01
相关资源
最近更新 更多