Getting many-to-many objects populated with Entity Framework 7

c# entity-framework entity-framework-core

Question

I have the following Many-To-Many relationship setup illustrated here by a database diagram: enter image description here

These are represented by the following POCO classes, from which the database was created using Entity Framework code first:

public class ExerciseCategory
{
    public int ExerciseId { get; set; }
    public Exercise Exercise { get; set; }
    public int CategoryId { get; set; }
    public Category Category { get; set; }
}

public class Exercise
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<ExerciseCategory> ExerciseCategories  { get; set; }
}

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<ExerciseCategory> ExerciseCategories { get; set; }
}

Now I need to get all exercises which would include the list of categories they belong to. Since it is a many-to-many relationship one exercise can have many categories. I tried the following code:

_context.Exercises
            .Include(e => e.ExerciseCategories)
            .OrderBy(e => e.Name).ToList();

But it does not populate the properties of ExerciseCategory...

How should I construct my query to get ExerciseCategory's Category property populated? Preferable in one query and not within a "for" loop, because potentially there will be many exercises displayed on one page and the performance might be an issue.

1
0
5/12/2016 4:19:51 PM

Popular Answer

Entity Framework 7 many-to-many support is still not complete. Currently you have to map one-to-many relationships manually for your Exercise and Category entities. Your entity classes are set up correctly. You now need to override OnModelCreating method in your DbContext class:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<ExerciseCategory>()
        .HasKey(t => new { t.ExerciseId, t.CategoryId });

    modelBuilder.Entity<ExerciseCategory>()
        .HasOne(pt => pt.Exercise)
        .WithMany(p => p.ExerciseCategories)
        .HasForeignKey(pt => pt.ExerciseId);

    modelBuilder.Entity<ExerciseCategory>()
        .HasOne(pt => pt.Category)
        .WithMany(t => t.ExerciseCategories)
        .HasForeignKey(pt => pt.CategoryId);
}

See Relationships - Entity Framework 7.0 Documentation

Also make sure to include DbSet<ExerciseCategory> property in you context.

After this the complete eager query can be constructed in following way:

_context.ExerciseCategories.Include(ec => ec.Exercise)
                    .Include(ec => ec.Category)
                    .Select(ec => ec.Exercise)

Or by using ThenInclude on Exercise-query:

_context.Exercises.Include(e => e.ExerciseCategories)
                  .ThenInclude(ec => ec.Category)
4
5/12/2016 5:15:45 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow