簡體   English   中英

如何遞歸加載所有子記錄?

[英]How can I load all child records recursively?

我有這個項目 class:

public class Project
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public List<Project> ChildProjects { get; set; }
    // more properties
}

這是我嘗試加載任何給定項目的所有后代:

private async Task<List<Project>> LoadDescendantsOf(Project project)
{
    project.ChildProjects = await db.Projects
        .Where(p => p.ParentId == project.Id)
        .ToListAsync();
    foreach (Project childProject in project.ChildProjects)
    {
        yield return childProject.ChildProjects = 
            await LoadDescendantsOf(childProject);
    }
}

...但它不起作用。 我得到的錯誤信息是

'ProjectsController.LoadDescendantsOf(Project)' 的主體不能是迭代器塊,因為 'Task>' 不是迭代器接口類型

我嘗試過使方法同步,但它是相同的錯誤消息,只是沒有“任務”部分。

我怎樣才能讓它工作?

您可以為此編寫簡單的擴展:

    public static IEnumerable<T> Traverse<T>(this T e, Func<T, IEnumerable<T>> childrenProvider)
    {
        return TraverseMany(new[] { e }, childrenProvider);
    }

    public static IEnumerable<T> TraverseMany<T>(this IEnumerable<T> collection, Func<T, IEnumerable<T>> childrenProvider)
    {
        var stack = new Stack<T>();
        foreach(var c in collection)
        {
            stack.Push(c);
        }
        while (stack.Count > 0)
        {
            var i = stack.Pop();
            yield return i;
            var children = childrenProvider(i);
            if (children != null)
            {
                foreach (var c in children)
                {
                    stack.Push(c);
                }
            }
        }
    }

和用法:

var allProjectIds = p.Traverse(x => x.ChildProjects).Select(x => x.Id).ToList();

如果要加載子項目,我建議為此在游標上編寫遞歸 SQL 過程,但這對小數據也有好處:

var allProjectIds = p
    .Traverse(x => 
    {
       x.ChildProjects = db.Projects
                           .Where(p => p.ParentId == project.Id)
                           .ToList();
       return x.ChildProjects;
    })
    .Select(x => x.Id)
    .ToList();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM