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

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

如果我有这样的两个聚合:

第一次聚合:

  • WorktimeRegulation(根)
  • 工作时间
  • 监管注册

数据澄清:

工作时间规定:

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

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

第二个聚合:

  • Shift(根)
  • 类次详情
  • 轮类入学

数据澄清:

类次:

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

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

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

我的问题:

  • 非聚合根 (ShiftDetail) 是否可以保存引用 对于另一个非聚合根 (WorkTime)?
  • 领域专家阐明:要创建有效的转变,那么我们 应该为每个与工作相关的工作时间有一个类次详细信息 具体的worktimeRegulation。如果 shiftDetails 中有引用,则无法更新 worktime 中的工时数。前面的例子表明我们 有两个工作时间(winter,summer),所以我们有一个shiftdetail winter 坚持 8 工作时间和 shiftdetail 夏天坚持6工作时间。现在我觉得由非聚合根(工作时间)控制的类次细节不变量如何强制这个不变量?

  • 根据之前的信息,我是否犯了与聚合规范相关的错误?

最佳答案

Is it okay for non aggregate-root (ShiftDetail) to hold a reference for another non aggregate-root (WorkTime)?

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

您只能持有对其他聚合根 ID 的引用。

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

Now I feel that invariant of shift details controlled by non-aggregate root(worktime) How to force this invariant?

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

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

  2. 由 Saga/流程经理协调。该组件对可能的多个聚合内部的变化使用react,并将命令发送到其他聚合。 Saga 与聚合相反。这种强制执行最终是一致的。

关于c# - 非聚合根可以保存另一个非聚合根的引用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52234819/

相关文章:

c# - 征求意见 : Intercepting changes to lists/collections

repository - 事件源聚合根是否应该有权访问事件源存储库?

c# - 将 linq 模型转换为通用列表

c# - 合并两个相同类型的表达式(没有 bool 值)

c# - 从 Active Directory PrincipalContext 获取所有用户

c# - 我想读取一个配置文件并将信息保存在一个对象中——这个解决方案好吗?

c# - 如何从 Sharepoint url 获取所有 SSRS 报告?

PHP OOP - getter setter 是否用于防止更改属性值?

python oop多态性

c# - 如何在 DDD 和存储库模式中对此建模