首页 > 解决方案 > 聚合根集合的更新 - 不符合 DDD。有效的替代品?

问题描述

在学习和实施领域驱动设计的同时,我正在开发一个约会计划系统。我已经确定了以下聚合根 - ScheduleDay

public class ScheduleDay : Entity, IAggregateRoot
{
    // Value Object - Full datetime and year, month, week, day values as integers
    public Day Day { get; }
    // Value Object - schedule for the day
    public Schedule Schedule { get; }
    
    // Other properties 

    private readonly List<Appointment> _appointments;
    // Value Object - Appointments for the day
    public IReadOnlyCollection<Appointment> Appointments => _appointments;

    // Functions for adding/managing appointments and schedule day
}

ScheduleDay 表示单个日历日,包含创建和管理约会所需的信息和业务逻辑。

问题- 如果我想用不同的时间表更新所有星期五怎么办?

据我所知并已阅读,领域驱动设计声明您一次只能使用一个聚合。这意味着(除非我错了)您不能同时加载聚合集合并更新它们。即使你可以 - 加载计划日期聚合的集合也可能会加载数千个约会,这将极大地影响性能,更不用说锁定数据库了。

潜在解决方案 (1)

使 Schedule 成为它自己的聚合。一周中的每一天(例如星期五)都有自己的聚合根。然后我可以将日程表的 ID 存储在 ScheduleDay 聚合中。

public class Schedule : Entity, IAggregateRoot { }

public class ScheduleDay : Entity, IAggregateRoot
{
    public Guid Schedule { get; }
}

当我想更新星期五的时间表时,我只会更新数据库中的 1 条记录。这个问题(?)是,如果我想进行新的约会,我必须首先从数据库加载日程安排,然后我需要加载日程安排日 - 两个 SQL 调用。

潜在解决方案 (2)

使 Schedule Root Aggregate 和 ScheduleDay 成为一个实体。

public class Schedule : Entity, IAggregateRoot 
{ 
    public ScheduleDay ScheduleDay { get; }
}

public class ScheduleDay : Entity { }

有了这个,我担心聚合太大(具有子实体集合的子实体的根实体),我读过的所有材料都表明聚合应该尽可能小。

标签: c#domain-driven-design

解决方案


聚合根背后的概念是:ScheduleDay 是完全独立的吗?除了与它们相关的时间表之外,你能有两个相等的 ScheduleDays 吗?

除此之外,将 Schedule 作为 IAggregateRoot 的解决方案看起来不错。只要确保您没有加载所有导航。如果您使用的是 EntityFramework,则可以使用 LazyLoading 代理。


推荐阅读