Как я могу установить свойство для каждого элемента предка в ветви дерева? - PullRequest
0 голосов
/ 26 февраля 2020

Я делаю простую систему управления проектами, и у меня есть эта модель для проекта:

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; }
}

Она определяется следующим образом: OnModelCreating():

modelBuilder.Entity<Project>()
    .HasMany(c => c.ChildProjects)
    .WithOne()
    .HasForeignKey(p => p.ParentId);

I Я хочу иметь некоторую функциональность для изменения свойства 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);
}

Метод SetParentCompleteness():

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;
}

Я знаю, что это не очень хорошая идея для UpdateRange(the_entire_database). Как мне составить список только тех проектов, которые нужно изменить?

1 Ответ

0 голосов
/ 27 февраля 2020

Давайте разберем логику c на 3 части.

Часть 1: вы хотите запросить все связанные проекты (ваше дерево). Для этого, да, вы хотите загрузить все проекты из БД, но на самом деле вам нужно загрузить только ProjectID, ParentID и статус. Вам не нужно загружать всю сущность (если у вашей сущности проекта много столбцов).

Часть 2: изменение статуса для всех запрашиваемых проектов. Теперь для этих загруженных идентификаторов вы можете загрузить весь необходимый проект (на этот раз весь объект) и изменить статус.

Часть 3: массовое обновление для всех проектов. Вы можете использовать что-то вроде этого (https://entityframework-extensions.net/bulk-update) для оптимизации производительности обновления.

...