📙
Learn EF Core 9
  • Introduction of Entity Framework Core
  • EF Core - AI Tools
  • What's New in EF Core 5
    • Simple Logging
    • Filtered Included
    • Backing Fields
    • Keyless Entity Types
    • Configure Precision and Scale
    • Translation of Contains on byte arrays
    • Many-to-many Relationship
    • Table-per-type (TPT) mapping
    • Required one-to-one Dependents
    • Support for Fields using Lambda
    • Drop Column from SQLite Database
    • Index Attribute
  • BulkExtensions in EF Core
  • Connection Strings: Entity Framework Core
  • Entity Framework Core Model
  • DbContext
  • DbSet
  • Relationship in EF-Core
  • Lazy Loading in EF Core
  • Migrations in EF-Core
  • Handling Concurrency in EF-Core
  • Raw SQL Queries in EF-Core
  • Database Providers
    • SQL Server
    • SQLite
    • InMemory
    • Cosmos
    • PostgreSQL
  • Project Types
    • Console
    • MVC
    • WinForm
    • Xamarin
    • Blazor
Powered by GitBook
On this page
  • Many-to-many Relationship
  • References
  1. What's New in EF Core 5

Many-to-many Relationship

PreviousTranslation of Contains on byte arraysNextTable-per-type (TPT) mapping

Last updated 1 year ago

Many-to-many Relationship

Earlier in Entity Framework, the many-to-many relationship was classified as two one-to-many relationships. To make it work the developer must create a joining entity class.

Now in Entity Framework Core 5.0, it will have full support for many-to-many relations without explicitly mapping the join table.

  • The navigation properties skip the join table and directly point to the other entity.

  • It will result in writing cleaner queries and simplify the use of the query result.

Let's consider the following model.

public class Movie
{
    public int MovieId { get; set; }
    public string Name{ get; set; }
    public Actor Actor { get; set; }
    public List<Genre> Genres { get; set; }
}

public class Genre
{
    public int GenreId { get; set; }
    public string GenreName { get; set; }
    public List<Movie> Movies{ get; set; }
}

As you can see that Movie class contains a collection of Genres, and Genre class contains a collection of Movies. EF Core 5.0 recognizes this as a many-to-many relationship by convention and there is no need for configuration in OnModelCreating.

public class MyEntityContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder opBuilder)
    {
        opBuilder.UseSqlServer("Data Source=(localdb)\\ProjectsV13;Initial Catalog=MyContextDB;");
    }

    public DbSet<Movie> Movies { get; set; }
    public DbSet<Genre> Genres { get; set; }

}

When you create migration or call the EnsureCreatedmethod, it will create the following tables including the join table.

CREATE TABLE [dbo].[Movies] (
    [MovieId] INT            IDENTITY (1, 1) NOT NULL,
    [Name]    NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_Movies] PRIMARY KEY CLUSTERED ([MovieId] ASC)
);

CREATE TABLE [dbo].[Genres] (
    [GenreId]   INT            IDENTITY (1, 1) NOT NULL,
    [GenreName] NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_Genres] PRIMARY KEY CLUSTERED ([GenreId] ASC)
);

CREATE TABLE [dbo].[GenreMovie] (
    [GenresGenreId] INT NOT NULL,
    [MoviesMovieId] INT NOT NULL,
    CONSTRAINT [PK_GenreMovie] PRIMARY KEY CLUSTERED ([GenresGenreId] ASC, [MoviesMovieId] ASC),
    CONSTRAINT [FK_GenreMovie_Genres_GenresGenreId] FOREIGN KEY ([GenresGenreId]) REFERENCES [dbo].[Genres] ([GenreId]) ON DELETE CASCADE,
    CONSTRAINT [FK_GenreMovie_Movies_MoviesMovieId] FOREIGN KEY ([MoviesMovieId]) REFERENCES [dbo].[Movies] ([MovieId]) ON DELETE CASCADE
);

Let's insert some movies and genres.

using (var context = new MyEntityContext())
{
    context.Database.EnsureCreated();

    var comedy = new Genre() { GenreName = "Comedy" };
    var action = new Genre() { GenreName = "Action" };
    var horror = new Genre() { GenreName = "Horror" };
    var scifi = new Genre() { GenreName = "Sci-fi" };

    context.AddRange(
        new Movie() { Name = "Avengers", Genres = new List<Genre>() { action, scifi } },
        new Movie() { Name = "Satanic Panic", Genres = new List<Genre>() { comedy, horror } });

    context.SaveChanges();

}

EF will then automatically create rows in the join table.

References

EF Core Many to Many
Improve EF Core performance with EF Extensions