在C#中将平面数据集合更改为嵌套树层次结构

时间:2018-05-30 15:12:45

标签: c# linq

我创建了一个组合多个外键表的视图。因此获取的数据如下所示:

@SerializedName

想要以这样的模型格式得到结果:

Id    Name    TagId    DepartmentId    Code
1     N1      T1       NULL            NULL
1     N1      T2       NULL            NULL
1     N1      NULL     D1              NULL
1     N1      NULL     NULL            C1
1     N1      NULL     NULL            C2
2     N2      T3       NULL            NULL
2     N2      NULL     D2              NULL

实现这一目标最简单有效的方法是什么?

2 个答案:

答案 0 :(得分:2)

您实际上没有向我们展示您尝试过的内容,但是如果您将整个视图数据放入内存中的IEnumerable,则可以使用Linq的GroupBy来定义组,您可以使用Linq过滤和投影来绘制每个组中的各种属性。

我假设Id and Name的基数为1:1,所以在Value Tuple分组键中使用了它。输出被投射为匿名类型。

您的最终输出需要Json序列化,但您可以在SO上找到任意数量的答案:

var groups = items.GroupBy(i => (i.Id, i.Name))
     .Select(grp => new 
     {
        grp.Key.Id, 
        grp.Key.Name, 
        TagIds = grp.Where(i => i.TagId != null)
                    .Select(x => x.TagId)
                    .ToArray(),
        DepartmentId = grp.FirstOrDefault(i => i.DepartmentId != null)?.DepartmentId,
        Codes = grp.Where(i => i.Code != null)
                    .Select(x => x.Code)
                    .ToArray(),
    });

测试数据:

var items = new[]{
    new {Id = 1, Name = "N1", TagId = "T1", DepartmentId = (string)null, Code = (string)null},
    new {Id = 1, Name = "N1", TagId = "T2", DepartmentId = (string)null, Code = (string)null},
    new {Id = 1, Name = "N1", TagId = (string)null, DepartmentId = "D1", Code = (string)null},
    new {Id = 1, Name = "N1", TagId = (string)null, DepartmentId = (string)null, Code = "C1"},
    new {Id = 1, Name = "N1", TagId = (string)null, DepartmentId = (string)null, Code = "C2"},
    new {Id = 2, Name = "N2", TagId = "T3", DepartmentId = (string)null, Code = (string)null},
    new {Id = 2, Name = "N2", TagId = (string)null, DepartmentId = "D2", Code = (string)null},
};

在LinqPad中输出看起来像这样:

LinqPads Console.Writeline Output of the above

答案 1 :(得分:0)

您可以使用Linq的GroupBy方法轻松完成此操作。 这是一个干净的例子:

var result = items.GroupBy(i => new { i.Id, i.Name })
                  .Select(g => new Result
                  {
                      Id = g.Key.Id,
                      Name = g.Key.Name,
                      TagIds = g.Select(i => i.TagId).ToList(),
                      DepartmentId = g.FirstOrDefault(i => i.DepartmentId != null)?.DepartmentId,
                      Codes = g.Select(i => i.Code).ToList();
                  });