我开始学习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属性)。
答案 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; }