如何在LINQ中将树形结构转换为表格形式

3

我有一个列表:

List<DataBanerModel> banerData = new List<DataBanerModel>();
banerData.Add(new DataBanerModel { Shop = 1, Cartoon = 1, Box = 1 });
banerData.Add(new DataBanerModel { Shop = 1, Cartoon = 1, Box = 2 });
banerData.Add(new DataBanerModel { Shop = 1, Cartoon = 1, Box = 3 });
banerData.Add(new DataBanerModel { Shop = 1, Cartoon = 2, Box = 1 });
banerData.Add(new DataBanerModel { Shop = 1, Cartoon = 2, Box = 2 });
banerData.Add(new DataBanerModel { Shop = 1, Cartoon = 2, Box = 3 });
banerData.Add(new DataBanerModel { Shop = 1, Cartoon = 3, Box = 1 });
banerData.Add(new DataBanerModel { Shop = 2, Cartoon = 1, Box = 1 });
banerData.Add(new DataBanerModel { Shop = 2, Cartoon = 1, Box = 2 });
banerData.Add(new DataBanerModel { Shop = 2, Cartoon = 1, Box = 3 });
banerData.Add(new DataBanerModel { Shop = 3, Cartoon = 1, Box = 1 });
banerData.Add(new DataBanerModel { Shop = 3, Cartoon = 1, Box = 2 });
banerData.Add(new DataBanerModel { Shop = 3, Cartoon = 1, Box = 3 });
banerData.Add(new DataBanerModel { Shop = 3, Cartoon = 2, Box = 1 });
banerData.Add(new DataBanerModel { Shop = 3, Cartoon = 2, Box = 2 });

我必须数一下有多少个盒子(Box)卡通片(Cartoon)里面,还要数一下有多少个卡通片(Cartoon)商店(Shop)里面,所以结果应该是这样的:

Shop: 1, Cartoons: 3, Boxes: 3
Shop: 1, Cartoons: 3, Boxes: 3
Shop: 1, Cartoons: 3, Boxes: 1
Shop: 2, Cartoons: 1, Boxes: 3
Shop: 3, Cartoons: 2, Boxes: 3
Shop: 3, Cartoons: 2, Boxes: 2

到目前为止,我写了:


var step4 = banerData.GroupBy(x => x.Shop)
    .Select(s => new
    {
        Shops = s.Key,
        Cartoons = s.GroupBy(y => y.Cartoon)
            .Select(k => new
            {
                k.Key,
                Boxes = k.GroupBy(z => z.Box)
                .Select(p => p.Key).ToList()
            }).ToList()
        }).ToList();

它运行良好,但我不知道如何展开这棵树。


这不像是一棵树形结构,而更像一个基本的表格。如果有什么,你正在尝试将其格式化为1:N关系 - 树的前身。而实际操作只是分组并使用聚合函数(如Count、Min、Max等)。这是相当基本的SQL内容,并且是LINQ从SQL复制的最初的事情之一:https://www.w3schools.com/sql/sql_groupby.asp - Christopher
3个回答

1

你可以使用:

  var grouped = banerData
    .GroupBy(d => d.Shop)
    .Select(g => new
    {
      Shop = g.Key,
      Cartoon = g.Select(i => i.Cartoon).Distinct().Count(),
      Box = g
        .GroupBy(i => i.Cartoon)
        .Select(gr => gr.Select(i => i.Box).Distinct().Count())
        .ToArray()
    }).SelectMany(i => i.Box.Select(ii => new { i.Shop, i.Cartoon, Box = ii }))
    .ToList();

你好,谢谢。不幸的是,你的代码结果是: { Shop = 1, Cartoon = 3, Box = {int[3]} } { Shop = 2, Cartoon = 1, Box = {int[1]} } { Shop = 3, Cartoon = 2, Box = {int[2]} } 这不是我预期的结果。 - Rafal010101
现在可以了。非常感谢。 - Rafal010101

0

你需要深入了解表达式,以下的LINQ代码将会在一个线性数据结构中产生你想要的结果:

var step4 = banerData.GroupBy(d => d.Shop).Select(g =>
            new 
            { 
              Shops = g.Key, 
              Cartoons = g.Select(d => d.Cartoon).Distinct().Count(), 
              Boxes = g.GroupBy(d => d.Cartoon).Select(c => c.Select(b=>b.Box).Distinct().Count()) 
            }).SelectMany(d => d.Boxes.Select(b => 
                new 
                { 
                  Shops = d.Shops, 
                  Cartoons = d.Cartoons, 
                  Boxes = b
                })).ToList();

0

从您的期望输出来看,我猜测Cartoon value是一个id而不是商店中卡通数量的数字。如果是这种情况,您需要将商店和卡通一起分组,然后获取计数。

因此,您可以这样做:

var grouped = banerData
    .GroupBy(b => new { b.Shop, b.Cartoon })
    .Select(x => new {
        x.Key.Shop,
        Cartoon = x.Select(e=> e.Cartoon).Count(), 
        Box = x.Select(e => e.Box).Count()
    }).ToList();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接