Linq to objects 聚合可选字段

Linq to objects aggregated optional fields

给定采购订单列表,其中一些已部分发货,一些已全部发货,我正在努力编写一个 linq to objects 查询,按月对订单进行分组并汇总订购数量和发货数量.

Public Class Order
Property OrderDate as Date
Property Items as List(Of OrderItem)
end Class

Public Class OrderItem
Property Sku as string
Property Qty as integer
Property Price as decimal
Property Shipments as list(Of Shipments)
End Class

Public Class Shipment
Property ShipmentDate as Date
Property OrderItem as OrderItem
Property ShippedQty as integer
end class

Dim Orders as List(Of Order)=GetOrdersFromSomewhere()
Dim Query=Orders.SelectMany(function(x) x.Items).SelectMany(function(y) y.Shipments)

但 Query 仅收集已发货的商品,跳过未发货的商品

您需要使用 GroupBy 然后执行 Sum.

你可以在classOrderItem,TotalPrice中添加一个方法来获取订单的总价,同样你可以定义一个获取AmountShipped价格的方法。在这里,我演示了 TotalPrice 方法来获取所有订单的总价格。

    Public Class OrderItem
    Property Sku as string
    Property Qty as integer
    Property Price as decimal
    Property Shipments as list(Of Shipments)

        Public Function TotalPrice() As Decimal
                    Return CDec(Me.Qty) * Me.Price
                End Function
        End Class

然后为了按日期对订单进行分组并获取总和,您可以使用以下代码

Dim orders = New GetOrdersFromSomewhere()
Dim ordersGroupedByDate = orders.GroupBy(Function(x) x.OrderDate)

For Each orderByDate As var In ordersGroupedByDate
    Dim dateTimeItem = orderByDate.Key
    Dim sumOfOrderedItems = orderByDate.SelectMany(Function(x) x.Items.[Select](Function(y) y.TotalPrice())).Sum()
Next

OrderDate
使用字符串格式 "yyyy-MM" 按月对订单进行分组 然后分别计算下单和发货数量

Dim orders As List(Of Order) = GetOrdersFromSomewhere()
Dim result = orders.GroupBy(Function(o) o.OrderDate.ToString("yyyy-MM")).
                    Select(Function(grp)
                               Return New With
                               {
                                   .Month = grp.Key,
                                   .OrderedSum = grp.Sum(Function(o) o.Items.Sum(Function(item) item.Qty)),
                                   .ShippedSum = grp.Sum(Function(o) o.Items.Sum(Function(item) item.Shipments?.Sum(Function(ship) ship.ShippedQty)))
                               }
                           End Function)

'Print result
For Each month In result
    Console.WriteLine($"{month.Month}{vbTab}Ordered: {month.OrderedSum}, Shipped: {month.ShippedSum}")
Next