Linq 层次结构的平面列表

Linq 层次结构的平面列表,linq,hierarchical-data,Linq,Hierarchical Data,我最难将文件夹列表转换为层次结构 Public Class Folder Public Property FolderID() As Integer Public Property Name() As String Public Property ParentFolderID() As Integer Public Property Children() as IEnumerable(Of Folder) End Class 我需要返回已填充子项的(文件夹)列表 我根据数据库中的数据建立一

我最难将文件夹列表转换为层次结构

Public Class Folder

Public Property FolderID() As Integer
Public Property Name() As String
Public Property ParentFolderID() As Integer
Public Property Children() as IEnumerable(Of Folder)

End Class
我需要返回已填充子项的(文件夹)列表

我根据数据库中的数据建立一个(文件夹)列表

{1,“文件夹1”,无任何内容} {2,“文件夹2”,1} {3,“文件夹3”,2} {4,“文件夹4”,3} {5,“文件夹5”,无任何内容}

我不知道如何递归地将子文件夹移动到其父文件夹的Children属性中

我想和林克一起做这件事

非常感谢您的帮助

更新

谢谢你的回答,但不完全是这样。根据你的回答,我想出了这个几乎有效的方法

Dim list = (From folder in folderList Select New Folder() With {
    .FolderID = folder.FolderID, 
    .Name = folder.Name, 
    .ParentFolderID = folder.ParentFolderID, 
    .Children = (From child in folderList 
                 Where child.ParentFolderID = item.FolderID).ToList()}).ToList()

{1, "Root", Nothing}
{2, "Child", 1}
{3, "Grand Child", 2}
我得到了三个文件夹的列表:

Root
--Child
Child
--Grand Child
Grand Child
应该是这样的:

Root
--Child
----Grand Child
C版本


虽然如果您在例如EF中进行了正确的映射,它应该自动完成。

如果您使用
ToLookup
扩展方法,则很容易

C#:

VB:


尝试以下扩展方法:

    public static IEnumerable<T> AsHierarchy<T>(this IEnumerable<T> collection,
        Func<T, T> parentSelector, Expression<Func<T, IEnumerable<T>>> childrenSelector, T root = default(T))
    {
        var items = collection.Where(x => parentSelector(x).Equals(root));
        foreach (var item in items)
        {
            var childrenProperty = (childrenSelector.Body as MemberExpression).Member as PropertyInfo;
            childrenProperty.SetValue(item, collection.AsHierarchy(parentSelector, childrenSelector, item), null);
        }
        return items;
    }

ToLookup extension.Hi的一个很好的用法。这段代码对我来说似乎很有趣,但如何调用它呢?我不明白x=>x的意思?有人能给我举个例子来指出正确的方向吗?你需要在一个静态类中创建上面的扩展方法来使用它。第一个参数指定如何查找父节点,第二个参数指定如何获取子集合。
var lookup = folderList.ToLookup(f => f.ParentFolderID);

foreach (var folder in folderList)
{
    folder.Children = lookup[folder.FolderID].ToList();
}

var rootFolders = lookup[null].ToList();
Dim lookup = folderList.ToLookup(Function (f) f.ParentFolderID)

For Each folder In folderList
    folder.Children = lookup(folder.FolderID).ToList()
Next

Dim rootFolders = lookup(Nothing).ToList()
    public static IEnumerable<T> AsHierarchy<T>(this IEnumerable<T> collection,
        Func<T, T> parentSelector, Expression<Func<T, IEnumerable<T>>> childrenSelector, T root = default(T))
    {
        var items = collection.Where(x => parentSelector(x).Equals(root));
        foreach (var item in items)
        {
            var childrenProperty = (childrenSelector.Body as MemberExpression).Member as PropertyInfo;
            childrenProperty.SetValue(item, collection.AsHierarchy(parentSelector, childrenSelector, item), null);
        }
        return items;
    }
list.AsHierarchy(x => x.Parent, x => x.Children);