0

If I have a Course class, that has a collection of students (ICollection<Person>) as follows:

public class Person
{
    public Person()
    {
        this.Courses = new HashSet<Course>();
    }

    public int PersonId { get; set; }
    [Required]
    public string PersonName { get; set; }

    public virtual ICollection<Course> Courses { get; set; }
}


public class Course
{
    public Course()
    {
        this.Students = new HashSet<Person>();
    }

    public int CourseId { get; set; }
    public string CourseName { get; set; }

    public virtual ICollection<Person> Students { get; set; }
}

I end up with this structure in the database (as expected):
enter image description here
(note the PersonCourses table)

However, in my example, I also want to add an instructor to the course. This instructor is also a Person, who can attend courses just like everyone else, so I adjust the above classes as shown below:

public class Person
{
    public Person()
    {
        this.Courses = new HashSet<Course>();
    }

    public int PersonId { get; set; }
    [Required]
    public string PersonName { get; set; }

    public virtual ICollection<Course> Courses { get; set; }
    public virtual ICollection<Course> InstructedCourses { get; set; }
}

public class Course
{
    public Course()
    {
        this.Students = new HashSet<Person>();
    }

    public int CourseId { get; set; }
    public string CourseName { get; set; }

    public virtual ICollection<Person> Students { get; set; }
    public virtual Person Instructor { get; set; }
}

What I was expecting to see is the same database structure as above, but with an additional table created that linked a person to many courses.

However, what I got was this:
enter image description here
(Note that the PersonCourses table has gone)

What I was Expecting/Hoping to see was similar to this: enter image description here

It's probably worth stating that the reason I've not got a separate Instructor/Person class is that I'm expecting that any Person can create a course, and thus become an instructor for that course.

Firstly - Is this possible to achieve via code-first in EF? I'm assuming so..
Secondly - What is it I'm doing wrong?
Thirdly - Is it the weekend yet?

All help appreciated :)

Sk93
  • 3,676
  • 3
  • 37
  • 67
  • Possible Answer: https://stackoverflow.com/questions/19342908/how-to-create-a-many-to-many-mapping-in-entity-framework. – Anton Toshik Jun 16 '17 at 10:01

1 Answers1

0

This is one reason I don't like / recommend code-first. It looks like EF got confused with the second InstructedCourses collection and instead just set up the instructor reference back from the course, though it seems to have just made the students collection a 1-to-many as well.

I would seriously consider either: A) changing you domain to define an Instructor entity vs. Student entity or B) Do schema first with the proper EF mappings to the tables you want.

I don't think any DBA is going to want to see things like course_personId / Person_personId throughout the schema that they are one day going to need to support and optimize.

Instructors and Students can extend a base "Person" class with either table per entity or an identifier. Course to instructor and course to student relationships can then be defined more clearly. The limitation would be if you wanted the same "person" to be able to be referenced as both an instructor and a student.

Steve Py
  • 26,149
  • 3
  • 25
  • 43