EF Core 5 多对多查询Include操作报不代表属性访问错误求解
错误原因
- EF Core 中的
Include和ThenInclude仅用于加载导航属性,也就是实体类中指向其他关联实体或实体集合的属性。你在ThenInclude中传入的pi.PizzaId是普通整型外键字段,不属于导航属性,不符合EF Core的关联数据加载规则,因此触发异常。 - 你当前的查询根实体已经是
DBPizza,不需要再通过中间表重复加载关联的披萨信息,你的需求本质是要加载每个披萨对应的配料数据。
修复方案
方案1:保留现有显式中间表的写法
直接修改查询语句,将 ThenInclude 的加载对象改为中间表的 Ingredient 导航属性即可,正确代码如下:
public async Task<List<DBPizza>> Pizzas() { return await _dataContext.Pizzas .Include(pizza => pizza.PizzaIngredients) .ThenInclude(pi => pi.Ingredient) .ToListAsync(); }
执行后返回的 DBPizza 对象就可以通过 PizzaIngredients 属性间接获取到所有关联的配料信息。
方案2(可选,EF Core 5及以上版本适用):简化多对多配置
如果你的中间表 DBPizzaIngredient 不需要存储额外字段(比如配料用量、添加时间等),可以删掉显式的中间类,简化配置:
- 修改两个实体类的导航属性:
public class DBPizza { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Required] public string Name { get; set; } [Required] public float Price { get; set; } // 直接关联配料集合,无需通过中间表中转 public List<DBIngredient> Ingredients { get; set; } } public class DBIngredient { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Required] public string Name { get; set; } // 直接关联披萨集合 public List<DBPizza> Pizzas { get; set; } }
- 删掉
OnModelCreating中关于中间表的配置,同时删掉DbContext中的DbSet<DBPizzaIngredient>定义,EF Core会自动生成隐式的中间关联表。 - 查询可以直接简化为:
public async Task<List<DBPizza>> Pizzas() { return await _dataContext.Pizzas .Include(pizza => pizza.Ingredients) .ToListAsync(); }
内容的提问来源于stack exchange,提问作者Doublon
相关产品推荐
相关产品推荐

