Search code examples
entity-frameworkentity-framework-coreef-code-first

EF Core many-to-many linq query


If I have the following classes mapping a many-to-many relationship in EF Core:

public class Book
{
    public int BookId { get; set; }
    public string Title { get; set; }
    public Author Author { get; set; }
    public ICollection<BookCategory> BookCategories { get; set; }
}  
public class Category
{
    public int CategoryId { get; set; }
    public string CategoryName { get; set; }
    public ICollection<BookCategory> BookCategories { get; set; }
}  
public class BookCategory
{
    public int BookId { get; set; }
    public Book Book { get; set; }
    public int CategoryId { get; set; }
    public Category Category { get; set; }
}

what is be the best practice to get a List<Category> from the Book instance? In EF6 I was able to just Query Book.Categories


Solution

  • If you're using EF Core 5.0 or later, you no longer need the BookCategory entity. You can simply have ICollection<Category> / ICollection<Book>, as you would have done with Entity Framework 6.

    public class Book
    {
        public int BookId { get; set; }
        public string Title { get; set; }
        public Author Author { get; set; }
        public ICollection<Category> Categories { get; set; }
    }  
    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
        public ICollection<Book> Books { get; set; }
    }  
    

    For EF Core 3.1 or earlier - which is the last version to support .NET Framework, so you may be stuck with it - you will need to include both levels of navigation properties, and then select the list of categories from that:

    Book book = await context.Books
        .Include(b => b.BookCategories).ThenInclude(c => c.Category)
        .First(b => b.Id == 42);
    
    List<Category> bookCategories = book.Categories
        .Select(c => c.Category)
        .ToList();