Editorials

Improved EF Many to Many

In keeping with the idea that Simple is better, today I share a comment from our reader, using the handle meilenberger62, simplifying the EF implementation published in yesterday’s editorial.

Our reader alters my implementation code down as follows:

Your example seems to works fine.

I don’t believe you need to add all that code to create the relationships.


If you add "public int EnrollmentID { get; set; } -or- public int ID { get; set; }" to the Enrollment class, it will use that as the primary key. It will also create the foreign keys for StudentId and ClassId in the Enrollment table because the objects for Student and Class are defined as "Virtual" in the Enrollment Class. It will also create non-unique indexes for StudentId and ClassId in the Enrollment table.


This is all you need if you want to use a natural key:


public class SchoolContext : DbContext

{

public DbSet<class> Classes { get; set; }

public DbSet<student> Students { get; set; }

public DbSet<enrollment> Enrollments { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)

{

var enrollmentEntity = modelBuilder.Entity<enrollment>();

enrollmentEntity.ToTable("Enrollment");

enrollmentEntity.HasKey(k => new {k.StudentiD, k.ClassId});

}
}

Note: this is only simplifying the relationship aspect of my implementation. It skips the notation that tells SQL Server how the column attributes are to be configured.

The basic difference in this implementation is that the Enrollment model is also defined as a DbSet<Enromment> Enrollments. This set definition, along with the generation of the key on StudentID and ClassID, are all that is necessary to implement the Many to Many relationship. It still identifies the non-standard name to use for the generated (or mapped) table, “Enrollment”.

An additional bonus of this implementation is that the Enrollment table now also has a unique primary key, EnrollmentID, which may be used to join this table to other tables in your database without referencing ClassID or StudentID. One danger of this implementation is that there is no unique constraint on the combination of ClassID and StudentID. These pairs should be unique, and may be used as an alternate key inside SQL Server.

Thanks for this helpful tip.

Cheers,

Ben