C# 如何为树分支上的每个祖先项设置属性?

C# 如何为树分支上的每个祖先项设置属性?,c#,recursion,tree,asp.net-core-mvc,C#,Recursion,Tree,Asp.net Core Mvc,我正在制作一个简单的项目管理系统,我有一个项目的模型: public class Project { public int Id { get; set; } public int? ParentId { get; set; } public string Title { get; set; } public string Notes { get; set; } public DateTime Created { get; set; } public

我正在制作一个简单的项目管理系统,我有一个项目的模型:

public class Project
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public string Title { get; set; }
    public string Notes { get; set; }
    public DateTime Created { get; set; }
    public DateTime? Deadline { get; set; }
    public bool Completed { get; set; }

    public List<Project> ChildProjects { get; set; }
}
如果需要更改,我想使用一些功能来更改所有祖先项目的
Completed
-属性。即,如果某个特定父项目的所有同级子项目都设置为已完成,则父项目的
completed
-属性应自动设置为
true
。然后对祖父母、曾祖父母等进行同样的检查

这就是我所拥有的:

创建或更新子项目时,我也会这样做:

// "project" is the current project we are creating or updating.
if (project.ParentId != null)
{
    List<Project> allProjects = await db.Projects.ToListAsync();
    List<Project> siblings = allProjects.Where(s => s.ParentId == project.ParentId).ToList();
    SetParentCompleteness(allProjects, project.Id, siblings.All(c => c.Completed));
    db.UpdateRange(allProjects);
}

我知道
更新(整个数据库)
不是一个好主意。如何列出需要更改的项目?

让我们将逻辑分解为三个部分

第1部分:要查询所有相关项目(树)。对于这一点,是的,您希望从DB加载所有项目,但实际上,您只需要加载ProjectID、ParentID和status。您不需要加载整个实体(以防您的项目实体有许多列)

第2部分:更改所有查询项目的状态。对于那些加载的ID,现在,您可以加载所有需要的项目(这次是整个实体)并更改状态


第3部分:所有项目的批量更新。您可以使用这样的()优化更新性能。

似乎是合理的逻辑,但为什么要编写
db.Projects.ToList()
这是一个非常糟糕的主意。不要做那么多急切的评估。还有,你可以得到这样的兄弟姐妹
project.Parent.Children
更简单。你需要懒惰loading@AluanHaddad如果我想要数据库中的所有项目,除了db.Projects.toListSync()之外还有什么选择?您不需要所有项目,只需要与正在更新的项目关联的项目
// "project" is the current project we are creating or updating.
if (project.ParentId != null)
{
    List<Project> allProjects = await db.Projects.ToListAsync();
    List<Project> siblings = allProjects.Where(s => s.ParentId == project.ParentId).ToList();
    SetParentCompleteness(allProjects, project.Id, siblings.All(c => c.Completed));
    db.UpdateRange(allProjects);
}
private void SetParentCompleteness(List<Project> allProjects, int id, bool completed)
{
    Project project = allProjects.Where(p => p.ParentId == id).FirstOrDefault();
    if (project != null)
    { 
        project.Completed = completed;
        db.Update(project);
        SetParentCompleteness(allProjects, project.Id, completed);
    }
    return;
}