实体框架代码优先中的许多许多关系;虚拟的“;关键字来访问对方
本文关键字:虚拟 关键字 访问 代码 框架 实体 许多许 关系 | 更新日期: 2023-09-27 18:29:41
此摘录代码成功创建了一个多关系,其中包含一个包含额外数据的显式Junction表。
问题:我希望能够访问Student的课程,反之亦然,
(因此是注释的虚拟属性。但如果我取消注释,它会导致错误(见下文))
如果我没有显式地创建一个连接表(没有额外的数据),那么virtual关键字仍然有效,因为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<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public void Run()
{
Database.SetInitializer(new DropCreateDatabaseAlways<ManyMany1>());
this.Courses.Add(new Course() {CourseName = "English"});
this.SaveChanges();
}
}
当我不服从公共虚拟。。。
错误:"无法确定类型'EF.Curse'和'EF.Student'之间的关联的主体端。必须使用关系fluent API或数据批注显式配置此关联的主体一端。"
public class Student
{
public virtual int StudentId { get; set; }
public virtual string StudentName { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
public class Course
{
public virtual int CourseId { get; set; }
public virtual string CourseName { get; set; }
public virtual ICollection<Enrollment> 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<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>()
.HasKey(student => student.StudentId);
modelBuilder.Entity<Course>()
.HasKey(course => course.CourseId);
modelBuilder.Entity<Enrollment>()
.HasKey(enrollment => new { enrollment.StudentId, enrollment.CourseId } );
modelBuilder.Entity<Student>()
.HasMany(student => student.Enrollments)
.WithRequired(enrollment => enrollment.Student)
.HasForeignKey(enrollment => enrollment.StudentId);
modelBuilder.Entity<Course>()
.HasMany(course => course.Enrollments)
.WithRequired(enrollment => enrollment.Course)
.HasForeignKey(enrollment => enrollment.CourseId);
}
}
关于这一点的老问题,在这里回答和更多信息:实体框架代码第一个多对多关系和其他信息。
编辑:用法示例:
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<Student>().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<Course> Courses { get; set; } // Many courses
}
public class Course
{
....
public virtual ICollection<Student> Students { get; set; } // Many students
}