非聚合根可以持有另一个非聚合根的引用吗?

时间:2018-09-08 11:23:11

标签: c# oop domain-driven-design aggregation aggregateroot

如果我有 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; } //... } 这样的人:

第一个集合:

  • WorktimeRegulation(Root)
  • 工作时间
  • 法规注册

数据澄清:

工作时间规定:

Id|    Name            |   NumberOfAvailableRotations|  IsActive 

 1|    General Rule    |          2                  |    true   

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

工作时间:

Id|  Name   |   NumberOfHours| NumberOfShortDays |WorkTimeRegulationId 

1 | Winter  |     8          |    1              |    1
2 | Summer  |     6          |    0              |    1

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

第二个汇总:

  • Shift(根)
  • ShiftDetail
  • ShiftEnrolment

数据澄清:

Shift:

Id|  Name      |  ShiftType  |  WorkTimeRegulationId  | IsDefault 
1 | IT shift   |  Morning    |    1                   |  1 

  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
        {
        }
        //..........
   }

ShiftDetail:

ShiftId  WorkTimeId shift-start  shift-end   
  1          1        08:00        16:00
  1          2        08:00        14:00

ShiftDetail

我的问题在这里

  • 非聚合根(WorkTime)可以保留引用吗? 另一个非聚合根(shift detail)?
  • 领域专家明确指出:要创建有效的班次,我们 每个与{a}相关的worktime应该有一个worktimeRegulation 特定的worktime。如果shiftDetails中有参考,则无法更新two worktimes(winter,summer)中的工作时间。前面的例子表明我们 有shiftdetai,所以我们有winter l 8坚持shiftdetail个工作时间,而summer坚持 6坚持工作worktime。现在,我感到由非聚合根(R2)控制的班次细节的不变性如何强制这种不变性?

  • 根据先前的信息,我是否犯了与集料规格有关的错误?

1 个答案:

答案 0 :(得分:1)

  

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

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

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

您可能持有另一个Aggregate中对嵌套实体ID的引用,但是您应该注意,该ID是不透明的,您可能不会假设其Aggregate根在内部如何使用它来查找嵌套实体。< / p>

  

现在,我感到轮班细节的不变性受非聚集根(工作时间)控制。如何强制这种不变性?

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

  1. 内部聚集。这意味着聚合必须足够大,必须拥有所需的所有状态。这种执行是非常一致的。

  2. 由Saga /流程经理协调。该组件对可能的多个聚合中的更改做出反应,并将命令发送到其他聚合。传奇是聚合的对立面。这种执行最终是一致的。