All Articles

EF Core 5.0 - Many to Many Relationship

inner peace

There is a new feature in EF 5.0 that change the way to create the Many-to-Many Relationship. It is really convenient way to create a relationship with Entities. Before dive into that let’s check that, how we create a many-to-many relationship in previous versions.

Before EF Core 5.0

Let’s take our common scenario with Post and Tag example. A blog post can have multiple tags and one tag can be tagged with many posts.

This is our Post entity.

public class Post
{
  public int Id { get; set; }
  public string Name { get; set; }
}

This is out Tag entity.

public class Tag
{
  public int Id { get; set; }
  public string Text { get; set; }
}

So these 2 entities have a many-to-many relationship. Let’s create the joining entity that contains all the mapping details with both entities.

public class PostTag
{
  public int PostId { get; set; }
  public Post Post { get; set; }

  public int TagId { get; set; }
  public Tag Tag { get; set; }
}

This PostId and TagId works as composite primary key

Now we need to add this mapping to our Post and Tag entities.

// inside the Tag.cs file
public ICollection<PostTag> PostTags { get; set; }
// inside the Post.cs file
public ICollection<PostTag> PostTags { get; set; }

Now we are at the last step. We use the Fluent APIto define the primary keys of the PostTag .

// inside the context class
// define composite primary key
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<PostTag>().HasKey(pt => new { pt.PostId, pt.TagId });
}

That’s it. Once we enable the migration this will create a table called PostTag and it has a composite primary key and has a relation with Post and Tag tables.

If you defined the keys in PostTag class differently you need to mention it in OnModelCreating by using Fluent API.

// in PostTag class
public int PId { get; set; }
public Post Post { get; set; }
// inside the OnModelCreating method in context class
modelBuilder.Entity<PostTag>()
      .HasOne<Post>(pt => pt.Post)
      .WithMany(p => p.PostTags)
      .HasForeignKey(pt => pt.PostId);

Hola, that is lots of code. Now let’s see how what are an improvement with EF Core 5.0

EF Core 5.0

Create the Post entity with navigation property.

public class Post
{
  public int Id { get; set; }
  public string Name { get; set; }
  public ICollection<PostTag> PostTags { get; set; }
}

Create the Tag entity with navigation property.

public class Tag
{
  public int Id { get; set; }
  public string Text { get; set; }
  public ICollection<PostTag> PostTags { get; set; }
}

That’s it. Now EF Core will identify this as a many-to-many relationship and it will create a table PostTag . The PostTag table data can be query and update without explicitly referring to that table. If we need more modification we can use Fluent API aswell.


I will wrap up this post from here. If you have anything to ask regarding this please leave a comment here. Also, I wrote this according to my understanding. So if any point is wrong, don’t hesitate to correct me. I really appreciate you.

That’s for today friends. See you soon. Thank you.

References:

What’s New in EF Core 5.0

Main image credit