如何使用linq来整理嵌套数据

时间:2012-10-14 15:09:08

标签: c# linq

我有一个类似这样的类别的表:

id parentid Title     
1  0        Parent1   
2  1        Child1        
3  0        Parent2
4  3        Child2
5  1        anotherChild1
6  3        anotherChild2

如何按此顺序对其进行排序:

Parent1
  child1
  anotherchild1
Parent2
  child2
  anotherchild2

并将订单保存到另一个名为sorted index?

的字段中

2 个答案:

答案 0 :(得分:1)

这适用于任何级别的层次结构

public void CustomSort()
{
    List<MyNode> nodes = new List<MyNode>();
    nodes.Add(new MyNode() { Id = 5, ParentId = 1, Title = "Anotherchild1" });
    nodes.Add(new MyNode() { Id = 6, ParentId = 3, Title = "Anotherchild2" });
    nodes.Add(new MyNode() { Id = 7, ParentId = 6, Title = "Anotherchild3" });
    nodes.Add(new MyNode() { Id = 1, ParentId = 0, Title = "Parent1" });
    nodes.Add(new MyNode() { Id = 2, ParentId = 1, Title = "Child1" });
    nodes.Add(new MyNode() { Id = 3, ParentId = 0, Title = "Parent2" });
    nodes.Add(new MyNode() { Id = 4, ParentId = 3, Title = "Child2" });

    Func<MyNode, List<int>> hierarchy = null;
    hierarchy = n =>
    {
        var n2 = nodes.FirstOrDefault(x => x.Id == n.ParentId);
        if (n2 != null) return hierarchy(n2).Concat(new List<int>() { n.Id }).ToList();
        return new List<int>() { n.ParentId,n.Id };
    };

    var debug = nodes.Select(x=>hierarchy(x)).ToList();

    var sortedList = nodes.OrderBy(n => String.Join(",", hierarchy(n).Select(x=>x.ToString("X8"))))
                          .ToList();
}

class MyNode
{
    public int Id;
    public int ParentId;
    public string Title;
}

Id  PId Title              hierarchy (key to sort)
1   0   Parent1             0 1
2   1   Child1              0 1 2
5   1   Anotherchild1       0 1 5
3   0   Parent2             0 3
4   3   Child2              0 3 4
6   3   Anotherchild2       0 3 6
7   6   Anotherchild3       0 3 6 7

答案 1 :(得分:0)

如果您的层次结构只有两个级别,那么您可以将父母与孩子一起加入,压缩结果列表,然后包含每个人的索引。

var parents = people.Where(p => p.ParentId < 1).ToList();
var children = people.Where(p => p.ParentId >= 1).ToList();

var ordered = (from parent in parents
               join child in children on parent.Id equals child.ParentId into childGroup
               from person in (new [] { parent }).Concat(childGroup)
               select person)
              .Select((person, sortedIndex) => new { person, sortedIndex });