使用Linq c#进行多级父子关系排序

时间:2015-03-17 13:40:00

标签: c# asp.net linq list guid

我有一个列表,我需要将其排序到此层次结构

{ Id=1, ParentId = null, Name = "Item1", Type="0"}
   { Id=2, ParentId = 1, Name = "ItemChild1", Type="1"}
   { Id=3, ParentId = 1, Name = "ItemChild2", Type="1"}
        { Id=4, ParentId = 3, Name = "ItemGrandChild1", Type="2"}
   { Id=5, **ParentId = 1**, Name = "ItemGrandChild2", Type="2"}

{ Id=6, ParentId = null, Name = "Item7", Type="0"}
...

与普通的父母子女关系不同,这里

Type2的项目可以是Type1或Type0的子项

所有Id都是guids

我见过可以使用Linq在子父排序上叠加答案。但我的情况有所不同。 使用Linq的任何优雅方式?

2 个答案:

答案 0 :(得分:0)

创建查找以快速查找子项并将它们投影到父集合。据我所知,如果你的孩子有不同的类型,只要他们知道哪个元素是他们的父母就完全不依赖。

public class TreeItem
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public IEnumerable<TreeItem> Children { get; set; }

    public void PrintAllChildren()
    { 
        this.PrintAllChildren(0);
    }

    private void PrintAllChildren(int indent)
    {
        Debug.WriteLine("{1}Item id: {0}", this.Id, string.Concat(Enumerable.Repeat<int>(0, indent).Select(i => " ")));
        if (this.Children != null)
            foreach (var item in this.Children)
                item.PrintAllChildren(indent + 1);
    }
}

public static class TreeItemExtension
{
    public static IEnumerable<TreeItem> GetAsTree(this IEnumerable<TreeItem> data)
    {
        var lookup = data.ToLookup(i => i.ParentId);
        return lookup[null].Select(i => {
            i.FillChildren(lookup);
            return i;
        });
    }
    private static TreeItem FillChildren(this TreeItem item, ILookup<int?, TreeItem> lookup)
    {
        item.Children = lookup[item.Id].Select(i => i.FillChildren(lookup));
        return item;
    }
}

答案 1 :(得分:0)

如果我是你,我会放弃尝试用linq或sql排序。抽象可能会有所帮助,但在这种复杂的情况下,它们会妨碍你。

如果您只是编写自己的分拣机,您将节省大量时间。

class MyCompare : IComparer<MyObject>
{
  public int Compare(x1, x2)
  {
      if (x1.parent == parent1 && x2.parent == parent2)
        return 1;
      if (x1.parent == x2.parent)
        return 0;
      //ect 
  }
}
List<MyObject> list = GetWeirdObjects();
list.Sort(new MyCompare());