entity framework代码中的许多关系首先使用“虚拟”关键字相互访问

此摘录代码与显式Junction表成功创建了许多关系,其中包含其他数据。

问题: 我希望能够从学生访问课程,反之亦然,
(因此注释的虚拟属性。但如果我取消注释它,它会导致错误(见下文))

如果我没有显式创建联结表(没有其他数据),则虚拟关键字可以正常工作,因为EF会按惯例创建联结表。

题:

如何在经过注册的情况下让学生访问课程? 或者那是不可能的? 如果不可能,那么最好的方法是什么呢?

EF和C#的初学者

public class Student { [Key] public int StudentId { get; set; } public string StudentName { get; set; } //public virtual Course Courses { get; set; } } public class Course { [Key] public int CourseId { get; set; } public string CourseName { get; set; } //public virtual Student Students { get; set; } } public class Enrollment { [Key] public int EnrollmentId { get; set; } public Student Student { get; set; } public Course Course { get; set; } public string Grade { get; set; } } public class ManyMany : DbContext, IContext { public DbSet Students { get; set; } public DbSet Courses { get; set; } public DbSet Enrollments { get; set; } public void Run() { Database.SetInitializer(new DropCreateDatabaseAlways()); this.Courses.Add(new Course() {CourseName = "English"}); this.SaveChanges(); } } 

当我解除公共虚拟……

错误: “无法确定类型’EF.Course’和’EF.Student’之间关联的主要结束。必须使用关系流畅的API或数据注释显式配置此关联的主要结尾。”

 public class Student { public virtual int StudentId { get; set; } public virtual string StudentName { get; set; } public virtual ICollection Enrollments { get; set; } } public class Course { public virtual int CourseId { get; set; } public virtual string CourseName { get; set; } public virtual ICollection Enrollments { get; set; } } public class Enrollment { public virtual int StudentId { get; set; } public virtual int CourseId { get; set; } public virtual string Grade { get; set; } public virtual Student Student { get; set; } public virtual Course Course { get; set; } } public class ManyMany : DbContext { public DbSet Students { get; set; } public DbSet Courses { get; set; } public DbSet Enrollments { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity() .HasKey(student => student.StudentId); modelBuilder.Entity() .HasKey(course => course.CourseId); modelBuilder.Entity() .HasKey(enrollment => new { enrollment.StudentId, enrollment.CourseId } ); modelBuilder.Entity() .HasMany(student => student.Enrollments) .WithRequired(enrollment => enrollment.Student) .HasForeignKey(enrollment => enrollment.StudentId); modelBuilder.Entity() .HasMany(course => course.Enrollments) .WithRequired(enrollment => enrollment.Course) .HasForeignKey(enrollment => enrollment.CourseId); } } 

关于这个问题的老问题,答案和更多信息: entity frameworkCodeFirst与其他信息的多对多关系 。

编辑:用法示例:

  var context = new ManyMany(); var physicsCourse = new Course() { CourseName = "Physics" }; var mathCourse = new Course() { CourseName = "Math" }; var studentJohn = new Student() { StudentName = "John Doe" }; var studentJane = new Student() { StudentName = "Jane Doe" }; var physicsCourseEnrollmentJohn = new Enrollment() { Student = studentJohn, Course = physicsCourse }; var mathCourseEnrollmentJohn = new Enrollment() { Student = studentJohn, Course = mathCourse }; var physicsCourseEnrollmentJane = new Enrollment() { Student = studentJane, Course = physicsCourse }; context.Courses.Add(physicsCourse); context.Courses.Add(mathCourse); context.Students.Add(studentJohn); context.Students.Add(studentJane); studentJohn.Enrollments.Add(physicsCourseEnrollmentJohn); studentJohn.Enrollments.Add(mathCourseEnrollmentJohn); studentJane.Enrollments.Add(physicsCourseEnrollmentJane); physicsCourse.Enrollments.Add(physicsCourseEnrollmentJohn); mathCourse.Enrollments.Add(mathCourseEnrollmentJohn); physicsCourse.Enrollments.Add(physicsCourseEnrollmentJane); context.Enrollments.Add(physicsCourseEnrollmentJohn); context.Enrollments.Add(mathCourseEnrollmentJohn); context.Enrollments.Add(physicsCourseEnrollmentJane); context.SaveChanges(); var johnsEnrollments = context.Students.Where(student => student.StudentId == studentJohn.StudentId).Single().Enrollments; MessageBox.Show(string.Format("Student John has enrolled in {0} courses.", johnsEnrollments.Count)); var janesEnrollments = context.Students.Where(student => student.StudentId == studentJane.StudentId).Single().Enrollments; MessageBox.Show(string.Format("Student Jane has enrolled in {0} courses.", janesEnrollments.Count)); 

entity framework无法自动确定“多对多”关系,因为它们是在SQL的其他表的帮助下表达的(在您的情况下,它是Enrollment )。 您可以直接在OnModelCreating方法中指定映射:

 public class YourDbContext : DbContext { .... protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity().HasMany(x => x.Courses).WithMany(x => x.Students) .Map(m => { m.ToTable("Enrollment"); // Relationship table name m.MapLeftKey("StudentID"); // Name of column for student IDs m.MapRightKey("CourseID"); // Name of column for course IDs }); } } 

另外,请注意,如果实体有许多其他实体,请使用集合进行关系:

 public class Student { .... public virtual ICollection Courses { get; set; } // Many courses } public class Course { .... public virtual ICollection Students { get; set; } // Many students }