簡體   English   中英

如何更好地編寫這個 EF core 6 Group by Query

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM