.NET November 11, 2020
5 min read

Entity Framework Core 5.0 — Many-to-Many Relationships

A new feature that is released with the new version of the Entity Framework Core is the possibility to create a Many-to-Many relationship without explicitly mapping the join table. On this article, we are going to see how we can create a Many-to-Many relationship using Entity Framework Core 5.

On the previous versions of EF Core, to create a many-to-many relationship, it’s necessary to have a third entity. For example, to create a many-to-many relationship between the entity Actor and the entity Movie, it is necessary to have three entities: Actor, Movie, and ActorMovie. On the article “Entity Framework Core Relationships with Fluent API”, I explain about how you can create this kind of relationship (using EF Core 3.1) and also show examples of how you can implement it in your code, you can read clicking here.

With Entity Framework Core 5.0, it’s not necessary to have this third entity, so now it’s possible to create a Many-to-Many relationship between Actor and Movie using only these two entities. For demonstration purpose, I’ve created a Console Application using .NET Core 3.1.

Because the focus of this article is to explain about the relationship between the entities, I’m using a very simple structure, with just one layer and simples model classes, but in a real-world project, you should create the DbContext class in a separated layer. If you want to know more about how can you create the structure of your project, you can check the article “Creating an Application from Scratch using .NET Core and Angular — Part 1” clicking here.

Many-to-Many (N:N)

Let’s create a Many-to-Many relationship. We will have two entities: the Movie and the Actor. One movie can have many actors, and one actor can have many movies.

This is the Actor class:

using System.Collections.Generic;

namespace EFCore5RelationshipsExamples.Models.ManyToMany
{
    public class Actor
    {
        public int Id { get; set; }
        public string Name { get; set; }

        /* EF Relations */
        public ICollection<Movie> Movies { get; set; }
    }
}

This is the Movie class:

using System.Collections.Generic;

namespace EFCore5RelationshipsExamples.Models.ManyToMany
{
    public class Movie
    {
        public int Id { get; set; }
        public string Name { get; set; }

        /* EF Relations */
        public ICollection<Actor> Actors { get; set; }
    }
}

Note thatActor contains a collection of Movies, and Movie contains a collection of Actors. EF Core 5 recognizes this as a many-to-many relationship by convention.

This is the class that inherits from DbContext class:

using EFCore5RelationshipsExamples.Models.ManyToMany;
using Microsoft.EntityFrameworkCore;

namespace EFCore5RelationshipsExamples
{
    public class EFCore5RelationshipsExamplesDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Server=(localdb)\MSSQLLocalDB;Database=EFCore5RelationshipsExamples;Trusted_Connection=True;MultipleActiveResultSets=true");
        }

        public DbSet<Actor> Actors { get; set; }
        public DbSet<Movie> Movies { get; set; }
    }
}

Note that is not necessary to add any code in OnModelCreating, and also it’s not necessary to have a third DbSet for ActorMovies, like we need to do in the previous version of EF Core.

In the Program class, in the Main method, we have the call to the seeding method:

static void Main(string[] args)
{
    using (var context = new EFCore5RelationshipsExamplesDbContext())
    {
        ManyToManyRelationship(context);
    }
}

This is the seeding method:

private static void ManyToManyRelationship(EFCore5RelationshipsExamplesDbContext context)
{
    var movie1 = new Movie { Name = "The Godfather" };
    var movie2 = new Movie { Name = "Scarface" };

    context.AddRange(
        new Actor
        {
            Name = "Marlon Brando",
            Movies = new List<Movie> { movie1 }
        },
        new Actor
        {
            Name = "Al Pacino",
            Movies = new List<Movie> { movie1, movie2 }
        });

    context.SaveChanges();
}

On the seeding method, we are creating and associating Actor and Movie entities and this will result in join table updates happening automatically. For example, after inserting the Actors and Movies, EF will then automatically create rows in the join table.

Let’s create the migration and update the database:

Add-Migration AddedManyToManyRelationship
Update-Database

We can see the relationship between the tables in the SQL Server:

Then we can run the application and check the data in the database:

For queries, Include and other query operations work just like for any other relationship. For example, this code is in the Program class, to print the values when the application is executed:

private static void PrintManyToManyRelationship()
{
    using (var context = new EFCore5RelationshipsExamplesDbContext())
    {
        foreach (var actor in context.Actors.Include(a => a.Movies))
        {
            Console.WriteLine($"\nActor: {actor.Name}");

            foreach (var movie in actor.Movies)
            {
                Console.WriteLine($"Movie: " + movie.Name);    
            }
        }
    }
}

This is the result:

Conclusion

This is an example of how to create a Many-to-Many relationship between the entities using EF Core 5.

You can check the code of this project on my GitHub: https://github.com/henriquesd/EFCore5RelationshipsExamples

If you like this solution, I kindly ask you to give a ⭐️ in the repository.

Thanks for reading!


References

What’s New in EF Core 5.0