多对多关系EF Code First

时间:2014-11-07 16:59:22

标签: entity-framework ef-code-first

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

 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; }


}

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

1 个答案:

答案 0 :(得分:2)

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

您必须将模型更改为:

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; }