繁体   English   中英

LINQ Sum使用GroupBy和OrderByDescending嵌套集合

[英]LINQ Sum Nested collection with GroupBy and OrderByDescending

我有:

public class Order
{
    public string Customer;
    public List<OrderLine> OrderLines;
}

public class OrderLine
{
    public decimal Quantity;
    public decimal UnitPrice;
}

我的目标是按降序金额搜索客户订单列表。 (金额==每个订单数量的加法* UnitPrice)

假设我们有2个客户的6个订单(Customer1,Customer2)。 每个客户都有3个orderLines。

我正在尝试:

var result = Database.GetAllOrders().OrderByDescending(order =>  
          order.Lines.Sum(ol=>ol.Quantity*ol.UnitPrice))
         .GroupBy(order=>order.CustomerName, 
         order=>order.Lines.Sum(ol=>ol.Quantity*ol.UnitPrice),
            (customerName, amount) => new {Customer=customerName, Amount=amount});

但我得到这样的东西:

顾客2:
- 金额:78
- 金额:89
- 金额:12

customer1表:
- 金额:64
- 金额:36
- 金额:28

虽然我想要寻求的是:

顾客2:
- 金额179

customer1表:
- 金额128

请问有什么建议吗?
非常感谢!

听起来您需要在订购之前进行分组和汇总,并且只按客户名称(或理想情况下,客户ID)进行分组:

var query = Database.GetAllOrders()
                    .GroupBy(order => order.CustomerName)
                    .Select(orders => new { 
                        Customer = orders.Key,
                        Amount = orders.Sum(o => o.OrderLines.Sum(
                                                 l => l.Quantity * l.UnitPrice))
                    })
                    .OrderByDescending(x => x.Amount);

Jon的答案是正确的,但是如果您打算使用此Amount属性来订购结果并显示,那么为什么不将它变成具体的属性呢?

public class Order
{
    public string Customer;
    public List<OrderLine> OrderLines;
    public decimal Amount
    {
        get
        {
            if (this.OrderLines == null)
                return 0;

            return this.OrderLines.Sum(o => o.Quantity * o.UnitPrice);
        }
    }
}

你仍在动态计算它,但是如果你用它来订购集合,然后想要显示它,那么你可能也想把它用于别的东西 - 把它当作一个访问属性。

这就是为什么我们有财产!


并实际回答这个问题,

var result = orders
    .GroupBy(o => o.CustomerName)
    .Select(g => new
    {
        CustomerName = g.Key,
        TotalAmount = g.Sum(o => o.Amount)
    })
    .OrderByDescending(g => g.TotalAmount));

我知道这不是一个具体的答案,但我有一个熟悉的挑战,并做到了这一点:

var elements = db.Orderheads
.Where(o => o.OrderDate.Value >= start && o.OrderDate.Value <= end)
.GroupBy(o => o.Employee)
.Select(g => new 
{
    Employee = g.Key,
    OrdersCount = g.Count(),
    TotalAmount = g.Sum(o => o.TotalExVat),
    TotalQuantity = g.SelectMany(o => o.Orderlines).Sum(ol => ol.QuantityOrdered)
})
.OrderByDescending(o => o.TotalAmount)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM