如果我有这样的两个聚合
:
第一次聚合:
- 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)
,所以我们有一个shiftdetai
lwinter
坚持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?
您可以通过两种方式强制执行不变量:
聚合内部。这意味着聚合必须足够大,它必须拥有它需要的所有状态。这种强制执行是高度一致的。
由 Saga/流程经理协调。该组件对可能的多个聚合内部的变化使用react,并将命令发送到其他聚合。 Saga 与聚合相反。这种强制执行最终是一致的。
关于c# - 非聚合根可以保存另一个非聚合根的引用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52234819/