Entity Framework Core Many-to-Many Relationship is configured through Fluent API. We first add collection navigation property on both the entities and then add the join entity type with the UsingEntity method.
Page Contents
Consider the 2 entity classes – Student & Teacher.
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Teacher
{
public int Id { get; set; }
public string Name { get; set; }
}
We first add collection navigation properties on both these entities towards one another.
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public IList<Teacher> Teacher { get; set; } //collection navigation property
}
public class Teacher
{
public int Id { get; set; }
public string Name { get; set; }
public IList<Student> Student { get; set; } //collection navigation property
}
Next on the DbContext OnModelCreating method we add join entity type with the UsingEntity method. In the below code we have given the name for this join entity as TeacherStudent.
public class SchoolContext : DbContext
{
public DbSet<Teacher> Teacher { get; set; }
public DbSet<Student> Student { get; set; }
public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//Write Fluent API configurations here
modelBuilder.Entity<Teacher>()
.HasMany(t => t.Student)
.WithMany(t => t.Teacher)
.UsingEntity(j => j.ToTable("TeacherStudent"));
}
}
When we perform the migrations, the Entity Framework Core will create the a join table by the name of TeacherStudent that will contains foreign keys to both Teacher and Student table records. Check the below image which explains this.
Many-to-Many relationship between the Student & Teacher entities will mean – one student can have many teachers and at the same time one teacher can have many students.
Related tutorial – EF Core – Fluent API One-to-Many Relationship.
For older versions of Entity Framework Core like 5.0 or previous versions, the procedure to create Many-to-Many relationship is different. Here we need to create a Joining Entity first. We named this joining entity as – Teacher Student. You can name it anything you like.
This joining entity will contain the foreign keys (reference navigation property) for both the other entities. These foreign keys will form the composite primary key for this joining entity.
The Teacher Student entity code must be as shown below.
public class TeacherStudent
{
public Student Student { get; set; }
public Teacher Teacher { get; set; }
}
Step 1 – Add foreign key property to other entities, in the joining entity.
public class TeacherStudent
{
public int StudentId { get; set; } //foreign key property
public Student Student { get; set; } //Reference navigation property
public int TeacherId { get; set; } //foreign key property
public Teacher Teacher { get; set; } //Reference navigation property
}
Step 2 – Add collection navigation property on the other entities towards the joining entity.
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public IList<TeacherStudent> TeacherStudent { get; set; } //collection navigation property
}
public class Teacher
{
public int Id { get; set; }
public string Name { get; set; }
public IList<TeacherStudent> TeacherStudent { get; set; } //collection navigation property
}
Step 3 – Next create DB Context OnModelCreating() method configure both the foreign keys in the joining entity as a composite key using Fluent API. See the below code.
modelBuilder.Entity<TeacherStudent>().HasKey(t => new { t.StudentId, t.TeacherId });
Step 4 – Create one-to-many relationship using Fluent API between the joining entity and other entities inside the OnModelCreating() method of the DB Context class.
modelBuilder.Entity<TeacherStudent>()
.HasOne(t => t.Student)
.WithMany(t => t.TeacherStudent)
.HasForeignKey(t => t.StudentId);
modelBuilder.Entity<TeacherStudent>()
.HasOne(t => t.Teacher)
.WithMany(t => t.TeacherStudent)
.HasForeignKey(t => t.TeacherId);
On performing EF Core Migrations we will get the Many-to-Many Relationship created as shown in the below image:
public class SchoolContext : DbContext
{
public DbSet<Teacher> Teacher { get; set; }
public DbSet<Student> Student { get; set; }
public DbSet<TeacherStudent> TeacherStudent { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(@"Server=vaio;Database=Company;Trusted_Connection=True;");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//Write Fluent API configurations here
modelBuilder.Entity<TeacherStudent>().HasKey(t => new { t.StudentId, t.TeacherId });
modelBuilder.Entity<TeacherStudent>()
.HasOne(t => t.Student)
.WithMany(t => t.TeacherStudent)
.HasForeignKey(t => t.StudentId);
modelBuilder.Entity<TeacherStudent>()
.HasOne(t => t.Teacher)
.WithMany(t => t.TeacherStudent)
.HasForeignKey(t => t.TeacherId);
}
}
Download the source code: