在C#中将树形结构递归添加到列表中

3

我有一些代码执行了一个Neo4j cypher查询,返回类型为FolderObjectIEnumerable,如下:

public IEnumerable<FolderObject> GetChild(string parentId)
{
    IEnumerable<FolderObject> childNode = null;
    var query = GraphConnection.Cypher
    .Start(new { n = Node.ByIndexLookup("node_auto_index", "ObjectId", parentId) })
    .Match("(n)-[r:HAS_FOLDER]->(b)")
    .Where("b.ParentId = n.ObjectId")
    .Return<FolderObject>("b");

    childNode = query.Results;

    return childNode;
}

FolderObject 的形式如下:

public string ObjectId { get; set; }
public string ParentId {get; set;}
public List<GraphObject> Children { get; set; }

我有一个方法,它运行良好:

public List<FolderObject> GetChildren(string repositoryId, string folderId)
{
    List<FolderObject> items;

    QueryOperations query = new QueryOperations(GraphConnection);

    var queryResult = query.GetChild(folderId);

    string childId = null;

    if (queryResult != null)
    {
        foreach (var item in queryResult)
        {
            childId = item.ObjectId;

            items = new List<FolderObject>();

            items.Add(item);

            var nextChild = GetChildren(repositoryId, childId);
        }
    }
    else
    {
        throw new Exception("The Folder with Id: " + folder + " could not be found.");
    }

    return items
}

现在问题出现在我尝试递归这样做时。我的需求是获取最顶层文件夹并将其添加到列表中,然后获取下面的次级文件夹并将其作为子文件夹添加进去。接着重复此过程直至没有更多子文件夹。
结构如下:
-Folder
    -Folder
        -Folder
            -Folder

并将此结构作为列表返回?

这是Json

{
    "ParentId": "0",
    "ObjectId": "1",
    "children": [
        {
            "ParentId": "1",
            "ObjectId": "2",
            "children": [
                {
                    "ParentId": "2",
                    "ObjectId": "3"
                }
            ]
        }
    ]
}

1
编写 "node:node_auto_index(ObjectId = '" + parentId + "')" 是允许 Cypher 注入攻击的一种好方法。请改用 Node.ByIndexLookup:它将保护您免受此类攻击。 - Tatham Oddie
1个回答

2

您可以使用 Stack<FolderObject>,它类似于递归方法,唯一的区别是它不是递归的。我的看法是,这种方式更易读,更简单。

public List<FolderObject> GetChildren(string repositoryId, string folderId)
{
    List<FolderObject> items = new List<FolderObject>();;

    QueryOperations query = new QueryOperations(GraphConnection);
    var queryResult = query.GetChild(folderId);

    Stack<FolderObject> folders = new Stack<FolderObject>(queryResult);

    while (folders.Count > 0)
    {
        FolderObject currentFolder = folders.Pop();
        var childId = currentFolder.ObjectId;
        items.Add(currentFolder);
        var nextChildren = GetChildren(repositoryId, childId);
        foreach (FolderObject child in nextChildren)
            folders.Push(child);
    }

    return items;
}

1
@MikeBarnes:不,循环不会在堆栈为空之前停止,而且无论foreach添加零个、一个还是一百万个文件夹都没有关系。 - Tim Schmelter
你不应该在一开始就实例化List<FolderObject> items=new List<FolderObject>();吗? - Mike Barnes
@MikeBarnes:请注意,我已更改了while循环条件并实例化了列表。列表中的结构/顺序应保持不变。试一下吧。 - Tim Schmelter
它可以正常工作,但它返回的数组中有22个项目,但实际上只应该有3个?其余的是重复的?它看起来像12232222.....等等,然而应该是123。我只是使用1、2、3作为ID。 - Mike Barnes
@MikeBarnes:我猜那是个bug,因为我已经在堆栈的构造函数中之后的foreach循环中添加了queryResult。在while循环之前删除foreach循环。我编辑了我的答案。 - Tim Schmelter
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接