【问题标题】:Linq transforming parent list of sub lists to be grouped by sub list entitiesLinq将子列表的父列表转换为按子列表实体分组
【发布时间】:2020-04-21 13:26:57
【问题描述】:

抱歉这个不清楚的标题,但我不知道如何命名。只显示它会更容易:

对象示例:

class Order
  {
     public string OrderNumber{ get; set; }
     public IEnumerable<ProductWithQuantity> ProductsWithQuantities{ get; set; }
  }

class ProductWithQuantity
  {
     public string ProductName{ get; set; }
     public int Quantity{ get; set; }
  }

假设我有IEnumerable&lt;Order&gt;,每个订单都有产品清单和数量。订单总是有相同的产品列表,只是数量不同。现在都是按订单分组的,怎么反过来按产品分组。

为了更好地可视化它,我将在伪 json 上展示我想要实现的目标。

当前生成的 json:

[
    {
        OrderNumber,
        ProductsWithQuantities [
            {ProductName, Quantity}
        ]
    }
]

我想实现这样的目标:

[
    {
        ProductName,
        OrdersWithQuantities [
            {OrderNumber, Quantity}
        ]
    }
]

我尝试使用 select 和 group by 但我无法解决。

【问题讨论】:

  • 对于旧情况,您已按OrderNumber 分组,现在您将按productName 分组?
  • 正确。它类似于从 excel 中获取的数据,其中左侧有 ProductNames 列表,每一列都是顺序。在每一行(产品)和列(订单)的交叉处都有数量。从 excel 中获取的数据结构基于列,但现在我需要将其转换为基于行(初始结构无法更改)。
  • 我已经提出了一个答案,请您检查一下

标签: linq .net-core data-transform


【解决方案1】:

1 - 通过考虑以下测试集合:

List<Order> orders = new List<Order>
{
    new Order
    {
        OrderNumber = "o1",
        ProductsWithQuantities = new List<ProductWithQuantity>
        {
            new ProductWithQuantity{ProductName = "p1", Quantity=1},
            new ProductWithQuantity{ProductName = "p2", Quantity=2},
        }
    },
    new Order
    {
        OrderNumber = "o2",
        ProductsWithQuantities = new List<ProductWithQuantity>
        {
            new ProductWithQuantity{ProductName = "p1", Quantity=1},
            new ProductWithQuantity{ProductName = "p2", Quantity=2},
        }
    }
};

2 - 您可以使用SelectManay 来展平所有产品。并通过构建新集合按ProductName 分组,如以下代码:

var result = orders
    .SelectMany(x => x.ProductsWithQuantities.Select(y => new { x.OrderNumber, y.ProductName, y.Quantity }))
    .GroupBy(p => p.ProductName)
    .Select(x => new 
        { 
            ProductName = x.Key, 
            OrderWithQuantities = x.Select(y => new { OrderNumer = y.OrderNumber, Quantity = y.Quantity }).ToList() 
        })
    .ToList();

3 - 演示

foreach(var item in result)
{
    Console.WriteLine($"{item.ProductName} : " +
        $"{string.Join(",", item.OrderWithQuantities.Select(x => $"{x.OrderNumer}::{x.Quantity}"))}");
}

4 - 结果:

p1 : o1::1,o2::1
p2 : o1::2,o2::2

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-15
    • 1970-01-01
    • 2018-05-18
    • 2010-09-29
    • 1970-01-01
    相关资源
    最近更新 更多