Как я могу загрузить все элементы-потомки какого-либо конкретного элемента или список элементов? - PullRequest
1 голос
/ 19 октября 2019

У меня есть эта модель проекта:

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

Я хочу загрузить все дочерние проекты и их ProjectOwner для всех проектов. В моей настройке нет заданного ограничения на длину хвоста потомков, пока мы не доберемся до «листа».

В данный момент я делаю это для Index -view (да, это ужасно!):

List<Project> projects = await db.Projects
    .Where(p => p.ParentId == null)
    .Include(o => o.ProjectOwner)

    .Include(c => c.ChildProjects)
        .ThenInclude(o => o.ProjectOwner)

    .Include(c => c.ChildProjects)
        .ThenInclude(c => c.ChildProjects)
            .ThenInclude(o => o.ProjectOwner)

    .Include(c => c.ChildProjects)
        .ThenInclude(c => c.ChildProjects)
            .ThenInclude(c => c.ChildProjects)
                .ThenInclude(c => c.ProjectOwner)

    .Include(c => c.ChildProjects)
        .ThenInclude(c => c.ChildProjects)
            .ThenInclude(c => c.ChildProjects)
                .ThenInclude(c => c.ChildProjects)
                    .ThenInclude(c => c.ProjectOwner)

    .Include(c => c.ChildProjects)
        .ThenInclude(c => c.ChildProjects)
            .ThenInclude(c => c.ChildProjects)
                .ThenInclude(c => c.ChildProjects)
                    .ThenInclude(c => c.ChildProjects)
                        .ThenInclude(c => c.ProjectOwner)

    // ... and so on ... (!)


    .ToListAsync();

Как я могу загрузить все более эффективным и динамичным способом? Код выше ограничен фиксированным количеством уровней. Я не могу этого получить.

Я задал похожий вопрос несколько дней назад, но не смог ничего сделать из ответов.

1 Ответ

0 голосов
/ 20 октября 2019

Иван Стоев дал мне этот комментарий в комментариях, для всех корневых элементов:

var rootProjects = db.Projects
    .Include(p => p.ProjectOwner)
    .Include(p => p.ChildProjects)
    .AsEnumerable()
    .Where(p => p.ParentId == null).ToList();

Так как не существует такого элегантного решения Linq для отфильтрованного набора, я просто сделал этоза один предмет:

Project project = await Task.FromResult(db.Projects
    .Include(p => p.ProjectOwner)
    .Include(p => p.ChildProjects)
        .ThenInclude(o => o.ProjectOwner)
    .AsEnumerable().Where(p => p.Id == id)
    .ToList().FirstOrDefault());
...