非聚合根可以保存另一个非聚合根的引用吗?

Any*_*are 5 c# oop domain-driven-design aggregateroot aggregation

如果我two aggregates喜欢这个:

第一集合:

  • WorktimeRegulation(Root)
  • 工作时间
  • RegulationEnrolment

澄清数据:

工作时间规定:

 public class WorkTimeRegulation : Entity<Guid>, IAggregateRoot
    {
        private WorkTimeRegulation()//COMB
       : base(Provider.Sql.Create()) // required for EF
        {
        }
        private WorkTimeRegulation(Guid id) : base(id)
        {
            _assignedWorkingTimes = new List<WorkingTime>();
            _enrolledParties = new List<RegulationEnrolment>();
        }
        private readonly List<WorkingTime> _assignedWorkingTimes;
        private readonly List<RegulationEnrolment> _enrolledParties;
        public string Name { get; private set; }
        public byte NumberOfAvailableRotations { get; private set; }
        public bool IsActive { get; private set; }
        public virtual IEnumerable<WorkingTime> AssignedWorkingTimes { get => _assignedWorkingTimes; }
       public virtual IEnumerable<RegulationEnrolment> EnrolledParties { get => _enrolledParties; }
        //...
    }
Run Code Online (Sandbox Code Playgroud)
Id|    Name            |   NumberOfAvailableRotations|  IsActive 

 1|    General Rule    |          2                  |    true   
Run Code Online (Sandbox Code Playgroud)

工作时间 :

public class WorkTime : Entity<Guid>
    {
        private WorkTime()
      : base(Provider.Sql.Create()) // required for EF
        {
        }
        private WorkTime(Guid id) : base(id)
        {
            ActivatedWorkingTimes = new List<WorkingTimeActivation>();
        }
        private ICollection<WorkingTimeActivation> _activatedWorkingTimes;

        public string Name { get; set; }
        public byte NumberOfHours { get; set; }
        public byte NumberOfShortDays { get; set; }
        public Guid WorkTimeRegulationId { get; private set; }
        public virtual ICollection<WorkingTimeActivation> ActivatedWorkingTimes { get => _activatedWorkingTimes; private set => _activatedWorkingTimes = value; }
        //....
   }
Run Code Online (Sandbox Code Playgroud)
Id|  Name   |   NumberOfHours| NumberOfShortDays |WorkTimeRegulationId 

1 | Winter  |     8          |    1              |    1
2 | Summer  |     6          |    0              |    1
Run Code Online (Sandbox Code Playgroud)

第二集合:

  • 转移(根)
  • ShiftDetail
  • ShiftEnrolment

澄清数据:

转变:

  public class Shift : Entity<Guid>, IAggregateRoot
    {
        private readonly List<ShiftDetail> _assignedShiftDetails;
        private readonly List<ShiftEnrolment> _enrolledParties;


        public string Name { get; set; }
        public ShiftType ShiftType { get; set; }
        public int WorkTimeRegulationId { get; set; }
        public bool IsDefault { get; set; }
        public virtual WorkingTimeRegulation WorkTimeRegulation { get; set; }
        public virtual IEnumerable<ShiftDetail> AssignedShiftDetails { get => _assignedShiftDetails; }
        public virtual IEnumerable<ShiftEnrolment> EnrolledParties { get => _enrolledParties; }
        //...........
   }
Run Code Online (Sandbox Code Playgroud)
Id|  Name      |  ShiftType  |  WorkTimeRegulationId  | IsDefault 
1 | IT shift   |  Morning    |    1                   |  1 
Run Code Online (Sandbox Code Playgroud)

ShiftDetail:

  public class ShiftDetail : Entity<Guid>
    {
        public Guid ShiftId { get; private set; }
        public Guid WorkTimeId { get; private set; }
        public DateTimeRange ShiftTimeRange { get; private set; }
        public TimeSpan GracePeriodStart { get; private set; }
        public TimeSpan GracePeriodEnd { get; private set; }
        public virtual WorkTime WorkTime { get; private set; }

        private ShiftDetail()
        : base(Provider.Sql.Create()) // required for EF
        {
        }
        //..........
   }
Run Code Online (Sandbox Code Playgroud)
ShiftId  WorkTimeId shift-start  shift-end   
  1          1        08:00        16:00
  1          2        08:00        14:00
Run Code Online (Sandbox Code Playgroud)

我的问题在这里:

  • 非aggregate-root(ShiftDetail)是否可以保存另一个非aggregate-root(WorkTime)的引用?
  • 领域专家澄清:要创建有效的班次,我们应该shift detail为每个worktime与特定的相关worktimeRegulation.并且worktime如果有参考,则无法更新工作时间shiftDetails.前面的例子表明,我们有two worktimes(winter,summer),所以我们有一个shiftdetai针对L winter坚持8workinghours和shiftdetail为 summer坚持6工作时间.现在我觉得由非聚合root(worktime)控制的移位细节的不变量如何强制这个不变量?

  • 根据以前的信息,我是否犯了与聚合规格有关的错误?

Con*_*enu 1

非聚合根(ShiftDetail)可以保存另一个非聚合根(WorkTime)的引用吗?

不,除非它们存在于同一个聚合中。

您只能保留对其他聚合根 ID 的引用。

您可以持有来自另一个聚合的嵌套实体 ID 的引用,但您应该注意,该 ID 是不透明的,您可能无法假设聚合根在内部如何使用它来查找嵌套实体。

现在我觉得轮班细节的不变量由非聚合根(工作时间)控制如何强制这个不变量?

您可以通过两种方式强制执行不变量:

  1. 在聚合内部。这意味着聚合必须足够大,它必须拥有它需要的所有状态。这种执行是高度一致的。

  2. 由 Saga/Process 经理协调。该组件对可能的多个聚合内的更改做出反应,并向其他聚合发送命令。Saga 与 Aggregate 相反。这种执行最终是一致的。