EFCore 和 C# 5.0 的多对多关系:如何从两个表中获取字段

问题描述

我在 Postgresql 中有以下数据库

ER Schema

编辑:在 PizzaTopping 中有一个唯一键,由字段 Id_Pizza、Id_Topping

构建

如您所见,这是一个多对多关系。

当我要求 Linqpad 6 从我的数据库搭建脚手架时,我得到以下结果:

Linqpad6 result

当我要求他们对我的数据库进行逆向工程时,我使用 EFCore Power Tools 时得到的结果相同。

从各种来源阅读,我发现,要求 EFCore 获取比萨饼的配料列表,我应该这样做:

Pizzas.Where(p=>p.Description=="Margherita")
      .Include(p=>p.PizzaToppings)
      .ThenInclude(p=>p.IdToppingNavigation)

查询 EFCore 5 返回此查询

SELECT P."Id_Pizza",P."Description",T0."Id_PizzaTopping",T0."Id_Pizza",T0."Id_Topping",T0."Id_Topping0",T0."Description"
FROM "Pizza" AS P
LEFT JOIN
    (SELECT P0."Id_PizzaTopping",P0."Id_Pizza",P0."Id_Topping",T."Id_Topping" AS "Id_Topping0",T."Description"
     FROM "PizzaTopping" AS P0
     INNER JOIN "Topping" AS T ON P0."Id_Topping" = T."Id_Topping") AS T0 ON P."Id_Pizza" = T0."Id_Pizza"
WHERE P."Description" = 'Margherita'
ORDER BY P."Id_Pizza",T0."Id_Topping0"

因为我想返回一个包含 Pizza 的列表,所以顶部如下:

margherita,mozzarella
margherita,tomato sauce
marinara,garlic
marinara,tomato sauce

我尝试添加 .Select(topping=>topping.description) 但它获取了比萨饼说明。

那么我怎样才能获得浇头描述他们在浇头表中的位置? 我试图在 .ThenInclude() 之后放一个 .Select() 但我仍然看到 Pizza 实体并且 p.PizzaToppings 不包含顶部表的属性描述。

解决方法

在这种情况下,您不需要 Include 而是 SelectMany 自定义投影:

var query = 
   from p in Pizzas
   from pt in p.PizzaToppings
   select new 
   {
      Pizza = p.Description,Topping = pt.IdToppingNavigation.Description
   }