Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
387 views
in Technique[技术] by (71.8m points)

c# - Many to many relationship mapping in EF Core

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...