问题描述
我有以下对象,其中“事件”是聚合对象:
public class Event
{
private List<CheckIn> _checkIns = new List<CheckIn>();
private List<Guid> _checkInrequiredFields = new List<Guid>();
public List<Registration> _registrations = new List<Registration>();
private List<Guid> _registrationrequiredFields = new List<Guid>();
public Guid Id { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public Guid EventType { get; private set; }
}
签入值对象:
public class CheckIn
{
private List<Field> _fields;
public CheckIn(Guid userId,DateTime date,List<Field> fields)
{
UserId = userId;
Date = date;
_fields = fields;
}
public Guid UserId { get; private set; }
public DateTime Date { get; private set; }
public IEnumerable<Field> Fields
{
get
{
return _fields.AsReadOnly();
}
}
}
字段值对象:
public class Field
{
public Field(Guid requiredFieldId,string value)
{
requiredFieldId = requiredFieldId;
Value = value;
}
public Guid requiredFieldId { get; private set; }
public string Value { get; private set; }
}
在添加新的签入并像这样更新聚合时,我无法决定如何处理此聚合的更新:
event.CheckIn(newCheckIn);
_eventRepository.Update(event);
处理更新 CheckIn 类型的列表的最佳方法是什么?我目前没有更改跟踪,也没有使用实体框架。我正在使用dapper调用存储过程来更新聚合,这些是我想出的选项:
- 更新事件后,删除所有签入,然后将它们重新插入。但是,许多人可以同时访问事件签入列表,这可能会导致一些数据丢失问题,直到他们重新加载(不太可行)。 / li>
- 在插入每个 CheckIn 值对象的存储过程中,检查表中是否已存在该对象,如果不存在,请不要插入。 (很容易解决,尽管我不确定当应用程序应该确定向数据库发送什么以进行更新时在数据库中添加此检查是否正确。)
- 重新考虑向 CheckIn 添加一个 Id ,并将其作为自己的汇总。
解决方法
在这种情况下,我倾向于在存储库中进行特定于用例的操作。请记住,您可能纯粹出于技术原因需要数据,但这并不一定意味着您的域需要在概念上进行更改。如果您的UserId
或UserId
/ Date
组合不是标识CheckIn
的唯一自然键,那么您当然可以添加Id
。但这并不意味着它成为实体/聚合实体,因为您纯粹出于技术原因而使用它。
添加/更改CheckIn
时,我会使用类似_eventRepository.SaveCheckIn(event,checkIn);
的名称来调用存储库,因为我知道我要做什么,并且Event
聚合正在处理一致性,并且已经通过,则表明存储库可以保留相关数据。