在实体框架代码优先多对多的关系,并使用"虚拟"关键字来访问对方 [英] Many-many relationship in Entity Framework Code First and using the "virtual" keyword to access each other

查看:183
本文介绍了在实体框架代码优先多对多的关系,并使用"虚拟"关键字来访问对方的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

本节选代码成功地创建了一个多对多与中它有附加数据的明确结表关系。



问题:我希望能够从学生,反之亦然,

(访问课程因此,评论虚拟属性。但如果我取消它,它会导致错误(见下文))



如果我不。'T明确创建一个路口表(没有额外的数据),虚拟关键字的工作但正如EF创建按照惯例结合表



问:

如何,我可以使学生进入课程的没有的经历扩招?或者是不可能的?如果这是不可能的,那么什么是去了解这一点的最好方法是什么?



在EF和C#的初学者)

 公共类学生
{
[关键]
公众诠释StudentId {搞定;组; }
公共字符串StudentName {搞定;组; }

//公共虚拟课程课程{搞定;组; }
}

公共类课程
{
[关键]
公众诠释CourseId {搞定;组; }
公共字符串课程名{获得;组; }

//公共虚拟学生学生{搞定;组; }
}

公共类招生
{
[关键]
公众诠释EnrollmentId {搞定;组; }
公共学生学生{搞定;组; }
公共课程课程{搞定;组; }
公共字符串等级{搞定;组; }
}

公共类ManyMany:的DbContext,IContext
{
公共DbSet<的Student GT;学生{搞定;组; }
公共DbSet<课程和GT;课程{搞定;组; }
公共DbSet<&招生GT;扩招{搞定;组; }

公共无效的run()
{
Database.SetInitializer(新DropCreateDatabaseAlways< ManyMany1>());
this.Courses.Add(新场(){课程名=英语});
this.SaveChanges();
}
}

当我取消公共虚拟...



错误:无法确定各类EF.Course'和'EF.Student之间的关联的主要结束该协会的主要终点必须是无论使用的关系流利的API或数据注解明确配置。


解决方案

 公共类学生
{
公共虚拟INT StudentId {搞定;组; }
公共虚拟字符串StudentName {搞定;组; }

公共虚拟的ICollection<&招生GT;扩招{搞定;组; }
}

公共类课程
{
公共虚拟INT CourseId {搞定;组; }
公共虚拟字符串课程名{获得;组; }

公共虚拟的ICollection<&招生GT;扩招{搞定;组; }
}

公共类招生
{
公共虚拟INT StudentId {搞定;组; }
公共虚拟INT CourseId {搞定;组; }
公共虚拟串级{搞定;组; }

公共虚拟学生学生{搞定;组; }
公共虚拟课程课程{搞定;组; }
}

公共类ManyMany:的DbContext
{
公共DbSet<的Student GT;学生{搞定;组; }
公共DbSet<课程和GT;课程{搞定;组; }
公共DbSet<&招生GT;扩招{搞定;组; }

保护覆盖无效OnModelCreating(DbModelBuilder模型构建器)
{
modelBuilder.Entity<学生>()
.HasKey(学生=> student.StudentId);
modelBuilder.Entity<课程和GT;()
.HasKey(当然=> course.CourseId);
modelBuilder.Entity<&招生GT;()
.HasKey(招生=>新建{enrollment.StudentId,enrollment.CourseId});

modelBuilder.Entity<的Student GT;()
.HasMany(学生=> student.Enrollments)
.WithRequired(招生=> enrollment.Student)
.HasForeignKey(招生=> enrollment.StudentId);
modelBuilder.Entity<课程和GT;()
.HasMany(当然=> course.Enrollments)
.WithRequired(招生=> enrollment.Course)
.HasForeignKey(招生= GT; enrollment.CourseId);
}
}



旧问题关于这一点,答案在这里更多的信息: 实体框架CodeFirst许多与其他信息一对多的关系



编辑:
用法例如:

  VAR语境=新ManyMany(); 

变种physicsCourse =新场(){课程名=物理};
变种mathCourse =新场(){课程名=加减乘除};

变种studentJohn =新学生(){StudentName =李四};
变种studentJane =新学生(){StudentName =李四};

变种physicsCourseEnrollmentJohn =新注册(){学生= studentJohn,课程= physicsCourse};
变种mathCourseEnrollmentJohn =新注册(){学生= studentJohn,课程= mathCourse};
变种physicsCourseEnrollmentJane =新注册(){学生= studentJane,课程= 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.StudentId == studentJohn.StudentId)。单()扩招;
MessageBox.Show(的String.Format(学生约翰先后就读于{0}课程。johnsEnrollments.Count));
VAR janesEnrollments = context.Students.Where(学生=> student.StudentId == studentJane.StudentId)。单()扩招;
MessageBox.Show(的String.Format(学生简先后就读于{0}课程。janesEnrollments.Count));


This excerpt code successfully creates a many-many relationship with an explicit Junction table that has additional data within it.

PROBLEM: I want to be able to access Courses from Student and vice versa,
(therefore the commented virtual property. But if I uncomment it, it causes an error (see below))

If I don't explicitly create a junction table (no additional data), the virtual keyword works though as EF creates a junction table by convention.

QUESTION:

How can I make Student access Courses without going through Enrollments? Or is that not possible? If it's not possible, then what's the best way to go about this?

(a beginner in EF and 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();
        }
    }

WHEN I UNCOMMENT public virtual...

ERROR: "Unable to determine the principal end of an association between the types 'EF.Course' and 'EF.Student'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations."

解决方案

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

Older question concerning this, answer and more info here: Entity Framework CodeFirst many to many relationship with additional information.

EDIT: Usage example:

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

这篇关于在实体框架代码优先多对多的关系,并使用&QUOT;虚拟&QUOT;关键字来访问对方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆