Many to many relationship mapping in EF Core

.net-core c# entity-framework-core many-to-many

Question

I have a problem with many to many relationship in EF core. I have the following model classes:

public class Meal
{
    public int Id { get; set; }
    [Required]
    public int Insulin { get; set; }
    public MealType Type { get; set; }

    public ICollection<MealFood> MealFoods { get; set; }

    public Meal()
    {
        MealFoods = new Collection<MealFood>();
    }
}

public class Food
{
    public int Id { get; set; }
    [StringLength(255)]
    public string Name { get; set; }
    [Required]
    public int Carbohydrates { get; set; }
    public ICollection<MealFood> MealFoods { get; set; }

    public Food()
    {
        MealFoods = new Collection<MealFood>();
    }
}

public class MealFood
{
    public int MealId { get; set; }
    public Meal Meal { get; set; }
    public int FoodId { get; set; }
    public Food Food { get; set; }
}

I have the following API resource class:

public class MealResource
{
    public int Id { get; set; }
    public int Insulin { get; set; }
    public MealType Type { get; set; }

    public ICollection<FoodResource> Foods { get; set; }

    public MealResource()
    {
        Foods = new Collection<FoodResource>();
    }
}

I have done the mapping in my DbContext:

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MealFood>().HasKey(mf => new { mf.MealId, mf.FoodId });
        modelBuilder.Entity<MealFood>().HasOne(mf => mf.Meal).WithMany(m => m.MealFoods).HasForeignKey(mf => mf.MealId);
        modelBuilder.Entity<MealFood>().HasOne(mf => mf.Food).WithMany(f => f.MealFoods).HasForeignKey(mf => mf.FoodId);
    }

I've got a problem with this call:

var meals = await context.Meals.Include(m => m.MealFoods).ToListAsync();

This returns almost everything I need, except the navigation properties from MealFoods

The reason why I want those properties, because I want to do the following mapping:

CreateMap<Meal, MealResource>().ForMember(mr => mr.Foods, opt => opt.MapFrom(x => x.MealFoods.Select(y => y.Food).ToList()));

I have already found this: Automapper many to many mapping

but (maybe I don't get something) this doesn't work because the property called Food in MealFood is null.

I hope I didn't explain too complex.

1
1
1/24/2018 8:24:32 PM

Accepted Answer

When you include navigation property, EF Core automatically fills the inverse navigation property, e.g. including Meal.MealFoods will automatically fill MealFood.Meal, including Food.MealFoods will automatically populate MealFood.Food etc. In order to populate other navigation properties you need to use additional ThenInclude. E.g.

var meals = await context.Meals
    .Include(m => m.MealFoods)
        .ThenInclude(mf => mf.Food) // <--
    .ToListAsync();

or

var foods = await context.Foods
    .Include(f => f.MealFoods)
        .ThenInclude(mf => mf.Meal) // <--
    .ToListAsync();
3
1/24/2018 8:24:25 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