Вы можете попробовать что-то вроде этого:
1) Создать класс узлов
class Node
{
public int ParentId { get; private set; }
public int Id { get; private set; }
public string Label { get; private set; }
public Node Parent { get; set; }
public List<Node> Children { get; } = new List<Node>();
public Node(int parentId, int id, string lable)
{
ParentId = parentId;
Id = id;
Label = lable;
}
public void AddChild(Node child)
{
child.Parent = this;
Children.Add(child);
}
public void Trace(int indent = 1)
{
Enumerable.Range(0, indent).ToList().ForEach(i => Console.Write(" - "));
Console.WriteLine(Label);
Children.ForEach(c => c.Trace(indent + 1));
}
}
2) Создать объекты узлов из ваших плоских данных и добавить их в словарь
var data = new List<DataRow>() {
new DataRow { ParentId = 0, Id = 1, Label = "parent" },
new DataRow { ParentId = 1, Id = 2, Label = "child 1" },
new DataRow { ParentId = 1, Id = 3, Label = "child 2" },
new DataRow { ParentId = 2, Id = 4, Label = "grand child 1" },
new DataRow { ParentId = 2, Id = 5, Label = "grand child 2" }
};
Dictionary<int, Node> nodes = data.ToDictionary(d => d.Id, d => new Node(d.ParentId, d.Id, d.Label));
3) Построить иерархию, просматривая все узлы, вызывающие AddChild для родителя
foreach (var node in nodes.Skip(1))
nodes[node.Value.ParentId].AddChild(node.Value);
Если вы вызовите Trace () для верхнего узла, выходные данные будут выглядеть следующим образом:
- parent
- - child 1
- - - grand child 1
- - - grand child 2
- - child 2