递归地将树结构添加到列表C#

递归地将树结构添加到列表C#,c#,recursion,neo4jclient,C#,Recursion,Neo4jclient,因此,我有一些代码执行Neo4j cypher查询,返回类型为FolderObject的IEnumerable,如下所示: public IEnumerable<FolderObject> GetChild(string parentId) { IEnumerable<FolderObject> childNode = null; var query = GraphConnection.Cypher .Start(new { n = Node.By

因此,我有一些代码执行Neo4j cypher查询,返回类型为
FolderObject
IEnumerable
,如下所示:

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;
}
然后我有一个很好的方法:

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
}
然后将此结构作为列表返回

这里是Json

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

您可以使用类似于递归方法的
堆栈
,唯一的区别是它不是递归的。我觉得它更易读,也不那么复杂

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;
}
公共列表GetChildren(字符串repositoryId、字符串folderId) { 列表项=新列表();; 查询操作查询=新的查询操作(GraphConnection); var queryResult=query.GetChild(folderId); 堆栈文件夹=新堆栈(queryResult); 而(folders.Count>0) { FolderObject currentFolder=folders.Pop(); var childId=currentFolder.ObjectId; 添加(当前文件夹); var nextChildren=GetChildren(repositoryId,childId); foreach(下一个孩子中的FolderObject孩子) 文件夹。推送(子文件夹); } 退货项目; }
谢谢,但是如果查询只返回一个结果有关系吗?@MikeBarnes:没有,因为循环不会在堆栈为空之前停止,而且无论
foreach
是否添加任何、一个或一百万个文件夹都没有关系。谢谢您的帮助,我现在就尝试一下@请注意,我刚刚删除了您的
items=newlist()从循环中删除,因为它总是清除循环中的无意义列表。由于代码未经测试,可能还有其他错误,但我想你已经明白了。结构是否仍然存在?编写“node:node_auto_index(ObjectId=”“+parentId+”)”是允许密码注入攻击的一个很好的方法。请改用Node.ByIndexLookup:它将保护您免受此影响。
{
    "ParentId": "0",
    "ObjectId": "1",
    "children": [
        {
            "ParentId": "1",
            "ObjectId": "2",
            "children": [
                {
                    "ParentId": "2",
                    "ObjectId": "3"
                }
            ]
        }
    ]
}
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;
}