In modern web applications, relationships between entities are a common occurrence. One of the most complex yet widely used relationships is the many-to-many relationship. In this blog post, we’ll explore how to implement and manage many-to-many relationships in .NET Core 8 using Entity Framework Core (EF Core).
What is a Many-to-Many Relationship?
A many-to-many relationship occurs when multiple records in one table are associated with multiple records in another table. For example:
-
Students and Courses: A student can enroll in multiple courses, and a course can have multiple students.
-
Books and Authors: A book can have multiple authors, and an author can write multiple books.
In relational databases, this relationship is typically implemented using a join table (also known as a bridging table or associative entity).
Setting Up the Project
Before diving into the code, ensure you have the following installed:
-
.NET Core 8 SDK
-
Visual Studio 2022 or Visual Studio Code
-
EF Core CLI tools (optional but recommended)
Create a new .NET Core 8 project:
dotnet new webapi -n ManyToManyDemo
cd ManyToManyDemo
Defining the Entities
Let’s use the Student and Course example to demonstrate a many-to-many relationship.
1. Student Entity
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
// Navigation property for the join table
public ICollection<StudentCourse> StudentCourses { get; set; }
}
2. Course Entity
public class Course
{
public int CourseId { get; set; }
public string Title { get; set; }
// Navigation property for the join table
public ICollection<StudentCourse> StudentCourses { get; set; }
}
3. Join Table Entity (StudentCourse)
The join table is explicitly defined to manage the relationship between Student
and Course
.
public class StudentCourse
{
public int StudentId { get; set; }
public Student Student { get; set; }
public int CourseId { get; set; }
public Course Course { get; set; }
}
Configuring the DbContext
In your DbContext
class, configure the many-to-many relationship using Fluent API.
public class ApplicationDbContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<StudentCourse> StudentCourses { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure the many-to-many relationship
modelBuilder.Entity<StudentCourse>()
.HasKey(sc => new { sc.StudentId, sc.CourseId }); // Composite primary key
modelBuilder.Entity<StudentCourse>()
.HasOne(sc => sc.Student)
.WithMany(s => s.StudentCourses)
.HasForeignKey(sc => sc.StudentId);
modelBuilder.Entity<StudentCourse>()
.HasOne(sc => sc.Course)
.WithMany(c => c.StudentCourses)
.HasForeignKey(sc => sc.CourseId);
}
}
Applying Migrations
Once the entities and DbContext are configured, create and apply the migrations:
dotnet ef migrations add InitialCreate
dotnet ef database update
This will generate the necessary tables in your database, including the StudentCourses
join table.
Seeding Data
Let’s seed some initial data to test the relationship.
Get All Students for a Course
var courseWithStudents = context.Courses
.Include(c => c.StudentCourses)
.ThenInclude(sc => sc.Student)
.FirstOrDefault(c => c.CourseId == 1);
foreach (var student in courseWithStudents.StudentCourses)
{
Console.WriteLine(student.Student.Name);
}
Conclusion
Many-to-many relationships are a powerful feature in relational databases, and EF Core makes it easy to implement and manage them in .NET Core 8. By following the steps outlined in this blog, you can efficiently model and query complex relationships in your applications.
Login to leave a comment.