从平面表中表示的父/子关系创建树

时间:2016-06-21 10:43:23

标签: c# linq

我有一个由存储过程返回的以下字段的C#列表:

var app = angular.module('myapp', []);
app.controller('myctrl', function($scope, $http) {
    $http.get("http://localhost:8080/xyz").then(function (response) {

    });
});

Reponse is :

[
  {
    "city": "animal"
  },
  {
    "city": "bird"
  }
]

我需要从此输出中构造一个嵌套对象列表

所以Carrier的每个对象都应该包含所有孩子的列表。任何人都可以帮我构建一个LINQ代码来实现这个目标吗?

期望的结果:

CarrierId   ParentCarrierId Name Descrition
1            NULL            A         AA
2              1             B         BB
3              1             C         CC
4              3             D         DD
5            NULL            E         EE

期望的结果应该如上所述

以下代码在树中排列,但子项仍然出现在列表中

  CarrierId = 1
      |__________________ CarrierId = 2
      |
      |__________________ CarrierId = 3
      |
      |                        |___________________ CarrierId = 4
CarrierId = 5

我不想要这种行为。如果某些内容显示为Child,则应将其从root中删除。

1 个答案:

答案 0 :(得分:5)

这就是你需要的。

首先,从源数据开始:

var source = new []
{
    new { CarrierId = 1, ParentCarrierId = (int?)null, Name = "A", Description = "AA", },
    new { CarrierId = 2, ParentCarrierId = (int?)1, Name = "B", Description = "BB", },
    new { CarrierId = 3, ParentCarrierId = (int?)1, Name = "C", Description = "CC", },
    new { CarrierId = 4, ParentCarrierId = (int?)3, Name = "D", Description = "DD", },
    new { CarrierId = 5, ParentCarrierId = (int?)null, Name = "E", Description = "EE", },
};

然后,按ParentCarrierId

创建查找
var lookup = source.ToLookup(x => x.ParentCarrierId);

现在我们需要一个输出结构:

public class Carrier
{
    public int Id;
    public List<Carrier> Children = new List<Carrier>();
    public string Name;
    public string Description;
}

然后,build函数按ParentCarrierId弹出所有运营商:

Func<int?, List<Carrier>> build = null;
build = pid =>
    lookup[pid]
        .Select(x => new Carrier()
        {
            Id = x.CarrierId,
            Name = x.Name,
            Description = x.Description,
            Children = build(x.CarrierId),
        })
        .ToList();

注意:它是递归的,因此需要使用初始= null进行定义。

最后我们建立:

List<Carrier> trees = build(null);

这给出了:

trees