Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding column in Entity Framework 6.1 - Many-To-Many - Code First

Just as an example I'm using the code from this article on codeproject: http://www.codeproject.com/Articles/234606/Creating-a-Many-To-Many-Mapping-Using-Code-First

enter image description here

Im trying to do something similar in my code but I also want a quantity property, so:

  1. One course can have many persons
  2. One Person can have many courses
  3. Each person can choose a quantity of each course. (I know that it does not make sense to choose the same course twice but it's just an example, or replace courses with types of hamburgers :-) )

I'm thinking I have to add a column in PersonCourses table named Quantity but I have no idea how to do that in Code First.

The code:

public class Person
{
  public int PersonId { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }

  public ICollection<Course> CoursesAttending { get; set; }

  public Person()
  {
    CoursesAttending = new HashSet<Course>();
  }
}

public class Course
{
  public int CourseId { get; set; }
  public string Title { get; set; }

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

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

public class SchoolContext : DbContext
{
  public DbSet<Course> Courses { get; set; }
  public DbSet<Person> People { get; set; }

  public SchoolContext()
    : base("MyDb")
  {
  }
}

Context:

public class SchoolContext : DbContext
{
  public DbSet<Course> Courses { get; set; }
  public DbSet<Person> People { get; set; }

  public SchoolContext()
    : base("MyDb")
  {
  }

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    modelBuilder.Entity<Course>().
      HasMany(c => c.Students).
      WithMany(p => p.CoursesAttending).
      Map(
       m =>
       {
         m.MapLeftKey("CourseId");
         m.MapRightKey("PersonId");
         m.ToTable("PersonCourses");
       });
  }
}
like image 999
Clint Eastwood Avatar asked Jun 21 '15 12:06

Clint Eastwood


1 Answers

To add a column to the junction table, you need to map it as an entity explicitly and create two one-to-many relationships:

public class PersonCourse
{
   [Key, Column(Order = 0),ForeignKey("Person")]
   public int PersonId { get; set; }
   [Key, Column(Order = 1),ForeignKey("Course")]
   public int CourseId { get; set; }

   public Person Person { get; set; }
   public Course Course { get; set; }

   public int Quantity{ get; set; }
}

public class Person
{
  public int PersonId { get; set; }
  //...

  public ICollection<PersonCourse> CoursesAttending { get; set; }

  public Person()
  {
    CoursesAttending = new HashSet<PersonCourse>();
  }
}

public class Course
{
  public int CourseId { get; set; }
  //...

  public ICollection<PersonCourse> Students { get; set; }

  public Course()
  {
    Students = new HashSet<PersonCourse>();
  }
}

If you want to use Fluent Api instead Data Annotations, you can use these configurations:

modelBuilder.Entity<PersonCourse>().HasKey(pc => new { pc.PersonId, pc.CourseId});

modelBuilder.Entity<PersonCourse>().HasRequired(pc=>pc.Person).WithMany(p=>p.CoursesAttending).HasForeignKey(pc=>pc.PersonId);

modelBuilder.Entity<PersonCourse>().HasRequired(pc=>pc.Course).WithMany(c=>c.Students).HasForeignKey(pc=>pc.CourseId);
like image 88
octavioccl Avatar answered Sep 22 '22 17:09

octavioccl