EF Core 中的多对多关系映射 [英] Many to many relationship mapping in EF Core
问题描述
我在 EF 核心中遇到多对多关系的问题.我有以下模型类:
公共课餐{公共 int Id { 获取;放;}[必需的]公共 int 胰岛素 { 得到;放;}公共膳食类型 { 获取;放;}公共 ICollection<MealFood>MealFoods { 得到;放;}公共餐(){MealFoods = 新系列();}}公共课食品{公共 int Id { 获取;放;}[字符串长度(255)]公共字符串名称 { 获取;放;}[必需的]公共整数碳水化合物{得到;放;}公共 ICollection<MealFood>MealFoods { 得到;放;}公共食品(){MealFoods = 新系列();}}公共课 MealFood{公共 int MealId { 获取;放;}公共餐餐{得到;放;}公共 int FoodId { 获取;放;}公共食品食品{得到;放;}}
我有以下 API 资源类:
公共类 MealResource{公共 int Id { 获取;放;}公共 int 胰岛素 { 得到;放;}公共膳食类型 { 获取;放;}公共 ICollection食物{得到;放;}公共膳食资源(){Foods = new Collection();}}
我已经在我的 DbContext 中完成了映射:
protected override void OnModelCreating(ModelBuilder modelBuilder){modelBuilder.Entity().HasKey(mf => new { mf.MealId, mf.FoodId });modelBuilder.Entity().HasOne(mf => mf.Meal).WithMany(m => m.MealFoods).HasForeignKey(mf => mf.MealId);modelBuilder.Entity().HasOne(mf => mf.Food).WithMany(f => f.MealFoods).HasForeignKey(mf => mf.FoodId);}
这个调用有问题:
var Meals = await context.Meals.Include(m => m.MealFoods).ToListAsync();
这将返回我需要的几乎所有内容,除了来自 MealFoods 的导航属性>
之所以想要那些属性,是因为我想做如下映射:
CreateMap().ForMember(mr => mr.Foods, opt => opt.MapFrom(x => x.MealFoods.Select(y => y.Food)).ToList()));
我已经找到了:Automapper 多对多映射
但是(也许我没有得到一些东西)这不起作用,因为 MealFood 中名为 Food 的属性为空.
希望我没有解释得太复杂.
当您包含导航属性时,EF Core 会自动填充反向导航属性,例如包括Meal.MealFoods
会自动填充MealFood.Meal
,包括Food.MealFoods
会自动填充MealFood.Food
等. 为了填充其他导航属性,您需要使用额外的 ThenInclude
.例如
var Meals = await context.Meals.Include(m => m.MealFoods).ThenInclude(mf => mf.Food)//<--.ToListAsync();
或
var food = await context.Foods.include(f => f.MealFoods).ThenInclude(mf => mf.Meal)//<--.ToListAsync();
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.
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();
这篇关于EF Core 中的多对多关系映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!