[英]How to better write this EF core 6 Group by Query
我正在查看 EF core 6 生成的查詢,但我對此並不滿意,因為它會產生很多阻塞開銷並且效率很高 TSQL 我希望我是問題所在......
我的 EF 查詢:
var query = db.PurchaseOrders
.Include(i => i.Items)
.Where(w=>w.Items.Any(a=>a.InventoryItemId==item.Id))
.GroupBy(g=>g.SupplierId)
.Select(s => new CurrentInventoryItemSupplier{ SupplierId=s.Key
, LastOrder= s.Max(m=>m.OrderDate)
, FirstOrder= s.Min(m=>m.OrderDate)
, Orders= s.Count()
}
).ToList();
生成這個:
SELECT [p].[SupplierId], (
SELECT MAX([p1].[OrderDate])
FROM [PurchaseOrders] AS [p1]
WHERE EXISTS (
SELECT 1
FROM [PurchasedItem] AS [p2]
WHERE ([p1].[Id] = [p2].[PurchaseOrderId]) AND ([p2].[InventoryItemId] = @__item_Id_0)) AND ([p].[SupplierId] = [p1].[SupplierId])) AS [LastOrder], (
SELECT MIN([p4].[OrderDate])
FROM [PurchaseOrders] AS [p4]
WHERE EXISTS (
SELECT 1
FROM [PurchasedItem] AS [p5]
WHERE ([p4].[Id] = [p5].[PurchaseOrderId]) AND ([p5].[InventoryItemId] = @__item_Id_0)) AND ([p].[SupplierId] = [p4].[SupplierId])) AS [FirstOrder], (
SELECT COUNT(*)
FROM [PurchaseOrders] AS [p7]
WHERE EXISTS (
SELECT 1
FROM [PurchasedItem] AS [p8]
WHERE ([p7].[Id] = [p8].[PurchaseOrderId]) AND ([p8].[InventoryItemId] = @__item_Id_0)) AND ([p].[SupplierId] = [p7].[SupplierId])) AS [Orders]
FROM [PurchaseOrders] AS [p]
WHERE EXISTS (
SELECT 1
FROM [PurchasedItem] AS [p0]
WHERE ([p].[Id] = [p0].[PurchaseOrderId]) AND ([p0].[InventoryItemId] = @__item_Id_0))
GROUP BY [p].[SupplierId]
(計划: https://www.brentozar.com/pastetheplan/?id=rkOloR7S9 )
理想情況下,我希望在這里
select
P.[SupplierId], MAX([p].[OrderDate]) as LastOrder, MIN([p].[OrderDate]) as FirtOrder, COUNT(P.Id) as Orders
FROM [PurchaseOrders] AS [p]
join [PurchasedItem] AS [p2] on [P2].[PurchaseOrderId]=[P].ID
where [p2].InventoryItemId= @__item_Id_0
group by P.[SupplierId]
( https://www.brentozar.com/pastetheplan/?id=rkOloR7S9 )
有沒有辦法改進生成的 TSQL 或制作參數化的 Function 並從 EF 核心調用 function?
這不可能在生產數據量中存活下來
好的,我想通了,我必須使用 Join 方法而不是 Include
這個:
var query = db.PurchaseOrders
.Join(db.PurchaseOrderItems, po => po.Id, pi => pi.PurchaseOrderId
, (po, pi) => new { SupplierId = po.SupplierId, OrderDate = po.OrderDate, pi.InventoryItemId })
.Where(w => w.InventoryItemId == item.Id)
.GroupBy(g => g.SupplierId)
.Select(s => new CurrentInventoryItemSupplier
{
SupplierId = s.Key,
LastOrder = s.Max(m => m.OrderDate),
FirstOrder = s.Min(m => m.OrderDate),
Orders = s.Count(),
});
產生
SELECT [p].[SupplierId], MAX([p].[OrderDate]) AS [LastOrder], MIN([p].[OrderDate]) AS [FirstOrder], COUNT(*) AS [Orders]
FROM [PurchaseOrders] AS [p]
INNER JOIN [PurchaseOrderItems] AS [p0] ON [p].[Id] = [p0].[PurchaseOrderId]
WHERE [p0].[InventoryItemId] = @__item_Id_0
GROUP BY [p].[SupplierId]
當你遍歷它時,它沒有任何問題:-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.