0

Today I got a question about how to create a many to many mapping using Entity Framework Code First fluent api. The problem is that the entity create an additional table beyond that was set for me.

 public class Person
{
    public Person()
    {
        courses = new HashSet<Course>();
    }
    public int PersonID { get; set; }
    public String Name { get; set; }
    public ICollection<Course> courses { get; set; }
}

public class Course
{
    public Course()
    {
        people = new HashSet<Person>();
    }
    public int CourseID { get; set; }
    public String Name { get; set; }
    public ICollection<Person> people { get; set; }
}

public class PersonCourse
{       
    public int fk_CourseID { get; set; }
    public virtual Course course { get; set; }

    public int fk_PersonID { get; set; }
    public virtual Person person { get; set; }

    public String AnotherInformation { get; set; }
}

public class PersonDataConfiguration : EntityTypeConfiguration<Person>
{
    public PersonDataConfiguration()
    {
        ToTable("Person");
        Property(c => c.Name).IsRequired();
        this.HasMany(c => c.courses).WithMany(t => t.people).Map(m => { m.MapLeftKey("CourseID"); m.MapRightKey("PersonID"); });
    }
}

public class CourseDataConfiguration : EntityTypeConfiguration<Course>
{
    public CourseDataConfiguration()
    {
        ToTable("Course");
        Property(c => c.Name).IsRequired();
        this.HasMany(c => c.people).WithMany(t => t.courses).Map(m => { m.MapLeftKey("PersonID"); m.MapRightKey("CourseID"); });
    }
}

public class PersonCourseDataConfiguration : EntityTypeConfiguration<PersonCourse>
{
    public PersonCourseDataConfiguration()
    {
        ToTable("PersonCourseX");
        HasKey(c => new { c.fk_CourseID, c.fk_PersonID });
        Property(c => c.AnotherInformation).IsRequired();
        this.HasRequired(c => c.person).WithMany().HasForeignKey(t => t.fk_PersonID);
        this.HasRequired(c => c.course).WithMany().HasForeignKey(t => t.fk_CourseID);
    }
}

public class ProgramTesteContext : DbContext
{
    public ProgramTesteContext()
        : base("MyConnectionString")
    {

    }

    public DbSet<Person> Person { get; set; }

    public DbSet<Course> Course { get; set; }

    public DbSet<PersonCourse> PersonCourse { get; set; }        

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {            
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();            
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
        modelBuilder.Properties<String>()
            .Configure(p => p.HasColumnType("varchar"));            
        modelBuilder.Properties<String>()
            .Configure(p => p.HasMaxLength(100));

        modelBuilder.Configurations.Add(new PersonDataConfiguration());
        modelBuilder.Configurations.Add(new CourseDataConfiguration());
        modelBuilder.Configurations.Add(new PersonCourseDataConfiguration());
    }        
}

The entity set up two tables for mapping: PersonCourseX created by me and another CoursePerson table containing only foreign keys without anotherinformation field. How to make this second table is not created?

1 Answers1

0

Change PersonCourseDataConfiguration as follows:

public class PersonCourseDataConfiguration : EntityTypeConfiguration<PersonCourse>
{
    public PersonCourseDataConfiguration()
    {
        ToTable("PersonCourseX");
        HasKey(c => new { c.fk_CourseID, c.fk_PersonID });
        Property(c => c.AnotherInformation).IsRequired();
        this.HasRequired(c => c.person).WithMany(c => c.courses).HasForeignKey(t => t.fk_PersonID);
        this.HasRequired(c => c.course).WithMany(c => c.people).HasForeignKey(t => t.fk_CourseID);
    }
}

Remove the commented lines:

public class PersonDataConfiguration : EntityTypeConfiguration<Person>
{
    public PersonDataConfiguration()
    {
        ToTable("Person");
        Property(c => c.Name).IsRequired();
        //this.HasMany(c => c.courses).WithMany(t => t.people).Map(m => { m.MapLeftKey("CourseID"); m.MapRightKey("PersonID"); });
    }
}

public class CourseDataConfiguration : EntityTypeConfiguration<Course>
{
    public CourseDataConfiguration()
    {
        ToTable("Course");
        Property(c => c.Name).IsRequired();
        //this.HasMany(c => c.people).WithMany(t => t.courses).Map(m => { m.MapLeftKey("PersonID"); m.MapRightKey("CourseID"); });
    }
}

Change Person and Course as follows:

public class Person
{
    //.. other properties
    public ICollection<PersonCourse> courses { get; set; }
}

public class Course
{
   //.. other properties
    public ICollection<PersonCourse> people { get; set; }
}
Fabio
  • 11,892
  • 1
  • 25
  • 41
  • Fabio, thank you for the answer, actually now the entity did not create additional table but created two additional foreign key fields to the PersonCourse table. Apart from fk_CourseID and fk_PersonID Entity created Course_CourseID and Person_PersonID fields – Adriano Silva Feb 23 '16 at 16:20
  • probably there is something wrong with `HasRequired(c => c.person).WithMany(c => c.courses).HasForeignKey(t => t.fk_PersonID);` Take a look at this line, make sure `HasForeignKey` was properly configured – Fabio Feb 23 '16 at 16:22