C# 如何使用Linq对象构建层次结构?

C# 如何使用Linq对象构建层次结构?,c#,linq,tree,C#,Linq,Tree,我有一个数据结构列表: public List<Personal> Personals() { return new List<Personal> { new Personal { Id = 0,

我有一个数据结构列表:

        public List<Personal> Personals()
        {
            return new List<Personal>
                {
                    new Personal
                        {
                            Id = 0,
                            Name = "Name 0"
                        },
                    new Personal
                        {
                            Id = 1,
                            Name = "Name 1",
                            ParentId = 0
                        },
                    new Personal
                        {
                            Id = 2,
                            Name = "Name 2",
                            ParentId = 0
                        },
                    new Personal
                        {
                            Id = 3,
                            Name = "Name 3",
                            ParentId = 0
                        },
                    new Personal
                        {
                            Id = 4,
                            Name = "Name 4",
                            ParentId = 1
                        },
                    new Personal
                        {
                            Id = 5,
                            Name = "Name 5",
                            ParentId = 1
                        },
                    new Personal
                        {
                            Id = 6,
                            Name = "Name 6",
                            ParentId = 2
                        },
                    new Personal
                        {
                            Id = 7,
                            Name = "Name 7",
                            ParentId = 2
                        },
                    new Personal
                        {
                            Id = 8,
                            Name = "Name 8",
                            ParentId = 4
                        },
                    new Personal
                        {
                            Id = 9,
                            Name = "Name 9",
                            ParentId = 4
                        },
                };
        }
public List Personals()
{
返回新列表
{
新个人
{
Id=0,
Name=“Name 0”
},
新个人
{
Id=1,
Name=“Name 1”,
ParentId=0
},
新个人
{
Id=2,
Name=“Name 2”,
ParentId=0
},
新个人
{
Id=3,
Name=“Name 3”,
ParentId=0
},
新个人
{
Id=4,
Name=“Name 4”,
ParentId=1
},
新个人
{
Id=5,
Name=“Name 5”,
ParentId=1
},
新个人
{
Id=6,
Name=“Name 6”,
ParentId=2
},
新个人
{
Id=7,
Name=“Name 7”,
ParentId=2
},
新个人
{
Id=8,
Name=“Name 8”,
ParentId=4
},
新个人
{
Id=9,
Name=“Name 9”,
ParentId=4
},
};
}
我想建一棵树:

public List<Tree> Trees()
            {
                return new List<Tree>
                    {
                        new Tree
                            {
                                Id = 0,
                                Name = "Name 0",
                                List = new List<Tree>
                                    {
                                        new Tree
                                            {
                                                Id = 1,
                                                Name = "Name 1",
                                                List = new List<Tree>
                                                    {
                                                        new Tree
                                                            {
                                                                Id = 4,
                                                                Name = "Name 4"
                                                            },
                                                        new Tree
                                                            {
                                                                Id = 5,
                                                                Name = "Name 5"
                                                            }
                                                    }
                                            }
                                    }
                            }
                    };
            }
公共列表树()
{
返回新列表
{
新树
{
Id=0,
Name=“Name 0”,
列表=新列表
{
新树
{
Id=1,
Name=“Name 1”,
列表=新列表
{
新树
{
Id=4,
Name=“Name 4”
},
新树
{
Id=5,
Name=“Name 5”
}
}
}
}
}
};
}
如何使用LinQ to对象构建树?我必须使用,但它不能完全工作,请参见以下内容:

public List<Tree> GetTree(List<Personal> list)
        {
            var listFormat = list.Select(x => new Tree
                {
                    Id = x.Id,
                    Name = x.Name,
                    ParentId = x.ParentId
                }).ToList();

            var lookup = listFormat.ToLookup(f => f.ParentId);
            foreach (var tree in listFormat)
            {
                tree.List = lookup[tree.Id].ToList();
            }

            return listFormat;
        }
公共列表GetTree(列表列表)
{
var listFormat=list.Select(x=>newtree
{
Id=x.Id,
Name=x.Name,
ParentId=x.ParentId
}).ToList();
var lookup=listFormat.ToLookup(f=>f.ParentId);
foreach(列表格式的变量树)
{
tree.List=lookup[tree.Id].ToList();
}
返回列表格式;
}

您应该使用递归:

public void SomeMethod() {
     // here you get your `list`
     var tree = GetTree(list, 0);
}

public List<Tree> GetTree(List<Personal> list, int parent) {
    return list.Where(x => x.ParentId == parent).Select(x => new Tree {
        Id = x.Id,
        Name = x.Name,
        List = GetTree(list, x.Id)
   }).ToList();
}
public void SomeMethod(){
//这是你的名单`
var-tree=GetTree(列表,0);
}
公共列表GetTree(列表,int父级){
返回列表。其中(x=>x.ParentId==parent)。选择(x=>newtree{
Id=x.Id,
Name=x.Name,
List=GetTree(List,x.Id)
}).ToList();
}

与上文相同,仅此代码检查根节点是否具有与其自身ID匹配的ParentID

    public void SomeMethod()
    {
        // here you get your `list`
        var tree = GetTree(list, 0);
    }

    public List<Tree> GetTree(List<Personal> list, int parent)
    {
        return list.Where(x => x.ParentId == parent).Select(x => new Tree
        {
            Id = x.Id,
            Name = x.Name,
            List = x.ParentId != x.Id ? GetTree(list, x.Id) : new List<Tree>()
        }).ToList();
    }
public void SomeMethod()
{
//这是你的名单`
var-tree=GetTree(列表,0);
}
公共列表GetTree(列表,int父级)
{
返回列表。其中(x=>x.ParentId==parent)。选择(x=>newtree
{
Id=x.Id,
Name=x.Name,
List=x.ParentId!=x.Id?GetTree(List,x.Id):新列表()
}).ToList();
}

如果您可以使用泛型类型构建树,请分享您的示例。感谢谢谢你的回答!但当我应用您的代码时,它会引发一个异常“System.StackOverflowException”。您可以再次检查。如果在
列表中有任何带有循环链接的项目,则可能会发生这种情况。例如:在下面添加了一个调整来处理某个人的根节点的ParentId=id的情况。这只会检测到两个节点直接相互引用为父节点的情况(#1->#2->#1->等等)。如果引入第三个节点(#1->#2->#3->#1->等),循环将再次出现。