如何使用LINQ按一个字段分组,在该分组中排序,并对该组合的值求和

本文关键字:排序 组合 求和 何使用 一个 字段 LINQ | 更新日期: 2023-09-27 18:26:10

我可以想出一种Rube Goldberg风格的方法来做到这一点,但我认为使用LINQ:可能可以更优雅、更简洁地完成

带有此类实例的通用列表:

public class PlatypusData
{
    public String MemberName { get; set; }
    public String CompanyName { get; set; }
    public String ReasonDescription { get; set; }
    public String TransactionType { get; set; }
    public int QtyOrdered { get; set; }
    public int QtyShipped { get; set; }
}

我想将其压缩为前四个类成员(MemberName、CompanyName、ReasonDescription、TransactionType)的唯一值的行或记录。

例如,使用这样定义的通用列表:

List<PlatypusData> _platypusDataList = new List<PlatypusData>();

该通用列表的内容可以是以下数据:

MemberName = "Ollie of Burkina Faso"
CompanyName = "Riley's Rugbeaters"
ReasonDescription = "Credit - Failed to deliver item (for credit adjustments only)"
TransactionType = "CREDIT ITEM"
QtyOrdered = 1
QtyShipped = 1
MemberName = "Oscar of Redlands"
CompanyName = "Herrera's Empty Frames"
ReasonDescription = [blank]
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 7
QtyShipped = 6
MemberName = "Ollie of Burkina Faso"
CompanyName = "Gatherer Mechanics"
ReasonDescription = "Credit - Product Quality (for credit adjutments only)"
TransactionType = "CREDIT ITEM"
QtyOrdered = 3
QtyShipped = 3
MemberName = "Ollie of Burkina Faso"
CompanyName = "Riley's Rugbeaters"
ReasonDescription = [blank]
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 42
QtyShipped = 42
MemberName = "Oscar of Redlands"
CompanyName = "Fidelity Fire"
ReasonDescription = "Credit - Failed to deliver item (for credit adjustments only)"
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 5
QtyShipped = 4
MemberName = "Oscar of Redlands"
CompanyName = "Herrera's Empty Frames"
ReasonDescription = [blank]
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 7
QtyShipped = 7
MemberName = "Ollie of Burkina Faso"
CompanyName = "Gatherer Mechanics"
ReasonDescription = [blank]
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 11
QtyShipped = 10
MemberName = "Oscar of Redlands"
CompanyName = "Fidelity Fire"
ReasonDescription = [blank]
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 6
QtyShipped = 7
MemberName = "Oscar of Redlands"
CompanyName = "Fidelity Fire"
ReasonDescription = [blank]
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 8
QtyShipped = 8
MemberName = "Ollie of Burkina Faso"
CompanyName = "Gatherer Mechanics"
ReasonDescription = [blank]
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 12
QtyShipped = 12

对于MemberName+CompanyName+ReasonDescription+TransactionType的每个唯一组合,我想将其压缩为一行,组合行的QtyOrdered和QtyShipped是这些值的总和,LINQ操作返回的数据按MemberName、CompanyName和ReasonDescription排序,例如:

MemberName = "Ollie of Burkina Faso"
CompanyName = "Gatherer Mechanics"
ReasonDescription = [blank]
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 23
QtyShipped = 22
MemberName = "Ollie of Burkina Faso"
CompanyName = "Gatherer Mechanics"
ReasonDescription = "Credit - Product Quality (for credit adjutments only)"
TransactionType = "CREDIT ITEM"
QtyOrdered = 3
QtyShipped = 3
MemberName = "Ollie of Burkina Faso"
CompanyName = "Riley's Rugbeaters"
ReasonDescription = [blank]
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 42
QtyShipped = 42
MemberName = "Ollie of Burkina Faso"
CompanyName = "Riley's Rugbeaters"
ReasonDescription = "Credit - Failed to deliver item (for credit adjustments only)"
TransactionType = "CREDIT ITEM"
QtyOrdered = 1
QtyShipped = 1

MemberName = "Oscar of Redlands"
CompanyName = "Fidelity Fire"
ReasonDescription = [blank]
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 14
QtyShipped = 15
MemberName = "Oscar of Redlands"
CompanyName = "Fidelity Fire"
ReasonDescription = "Credit - Failed to deliver item (for credit adjustments only)"
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 5
QtyShipped = 4
MemberName = "Oscar of Redlands"
CompanyName = "Herrera's Empty Frames"
ReasonDescription = [blank]
TransactionType = "REGULAR ITEM - ON SPEC"
QtyOrdered = 14
QtyShipped = 13

我认为需要GroupBy、OrderBy和Sum的一些组合,但不知道如何做到这一点(以LINQ/非戈德堡式的方式)。

如何使用LINQ按一个字段分组,在该分组中排序,并对该组合的值求和

我认为需要组合GroupBy、OrderBy和Sum

你说得对。这应该是你需要的:

var result = _platypusDataList
    .GroupBy(i => new { i.MemberName, i.CompanyName, i.ReasonDescription, i.TransactionType })
    .Select(g => new
        {
            g.Key.MemberName,
            g.Key.CompanyName,
            g.Key.ReasonDescription,
            g.Key.TransactionType,
            QtyOrdered = g.Sum(i => i.QtyOrdered),
            QtyShipped = g.Sum(i => i.QtyShipped)
        })
    .OrderBy(i => i.MemberName)
    .ThenBy(i => i.CompanyName)
    .ThenBy(i => i.ReasonDescription)
    .ToList();

上面的代码返回一个匿名类型的列表。如果您想要List<PlatypusData>,则需要修改Select:

.Select(g => new PlatypusData
    {
        MemberName = g.Key.MemberName,
        CompanyName = g.Key.CompanyName,
        ReasonDescription = g.Key.ReasonDescription,
        TransactionType = g.Key.TransactionType,
        QtyOrdered = g.Sum(i => i.QtyOrdered),
        QtyShipped = g.Sum(i => i.QtyShipped)
    })