Entity Framework many-to-many relationship

While optimising a query, I noticed that a many-to-many relationship still used a class in between. There is a more optimised way to configure many-to-many relationships in Entity Framework.

Before, many-to-many relationships looked like:

[Table("dbo.Book")]
public class Book
{
  [Key]
  public int Id { get; set; }
  public virtual ICollection Authors { get; set; }
}
[Table("dbo.BookAuthor")]
public class BookAuthor
{
  [Key]
  public int BookId { get; set; }
  [Key]
  public int AuthorId { get; set; }
}
[Table("dbo.Author")]
public class Author
{
  [Key]
  public int Id { get; set; }
  public virtual ICollection Authors { get; set; }
}

There is a much more compact way of describing it:

 [Table("dbo.Person")]
public class Book
{
  [Key]
  public int Id { get; set; }
  public virtual ICollection Authors { get; set; }
}
public class Author {
  [Key]
  public int Id { get; set; }
  public virtual ICollection Books { get; set; }
}
public class MyContext : DbContext
{
  public void OnModelCreating(DbModelBuilder modelBuilder)
  {
<code><span class="pln">    modelBuilder</span><span class="pun">.</span><span class="typ">Entity</span><span class="pun">&lt;Author</span><span class="pun">&gt;()
      .</span><span class="typ">HasMany</span><span class="pun">&lt;</span><span class="typ">Order</span><span class="pun">&gt;(a =&gt; a.Books</span><span class="pun">)</span>
      <span class="pun">.</span><span class="typ">WithMany</span><span class="pun">(b =&gt; b.Authors</span><span class="pun">)</span>
      <span class="pun">.</span><span class="typ">Map</span><span class="pun">(map</span> <span class="pun">=&gt;</span>
         <span class="pun">{</span><span class="pln">
           map</span><span class="pun">.</span><span class="typ">MapLeftKey</span><span class="pun">(</span><span class="str">"BookId"</span><span class="pun">);</span><span class="pln">
           map</span><span class="pun">.</span><span class="typ">MapRightKey</span><span class="pun">(</span><span class="str">"AuthorId"</span><span class="pun">);</span><span class="pln">
           map</span><span class="pun">.</span><span class="typ">ToTable</span><span class="pun">(</span><span class="str">"BookAuthor"</span><span class="pun">);</span>
         <span class="pun">});
</span></code> }
}

The OnModelCreating method will tell Entity Framework to add a many-to-many relationship between the Book and Author table. In the back it will use a link table named BookAuthor. Now, you won’t see this little table anymore. One less step to take and to make your code a bit more readable. Just make sure the MapLeftKey and MapRightKey are set correctly, otherwise an existing table will map the wrong items to each other.

Btw, thanks Stack Overflow.

 

Advertisements