我在DDD有界上下文中使用多个聚合根。
例如
public class OrderAggregate
{
public int ID {get;set;}
public string Order_Name {get;set;}
public int Created_By_UserID {get;set;}
}
public class UserAggregate
{
public int ID {get;set;}
public string Username {get;set;}
public string First_Name {get;set;}
public string Last_Name {get;set;}
}
我使用SQL关系库来持久保存域对象。每个聚合根与一个存储库匹配。
如果我想找到一个由John Doe创建的订单(多个聚合的搜索),DDD的方式是什么?
将First_Name和Last_Name添加到OrderAggregate中,以便在OrderRespository中添加FindByUserFirstLastName方法,但这可能会引发两个聚合根之间的数据一致性问题
创建一个原始的SQL查询并直接访问数据库以跨越搜索"存储库"
使用"发现者"为了直接从DB
将查询完成所需的数据复制到新的聚合根,例如
public class QueryOrderAggregate
{
public int ID { get; set; }
public string Order_Name { get; set; }
public int Created_By_UserID { get; set; }
public string First_Name { get; set; }
public string Last_Name { get; set; }
}
答案 0 :(得分:1)
如果我想找到一个由John Doe创建的订单(多个聚合的搜索),DDD的方式是什么?
与访问聚合的方式几乎相同...
您创建一个存储库,该存储库提供(您的域中此视图/报告的名称)。它可能使用UserId作为标识报告的关键。在存储库的实现中,实现可以做任何有意义的事情 - SQL连接是一个合理的起点。
视图/报告基本上是一种值类型;它是不可变的,可以提供数据,但是没有任何方法,或者对聚合根的任何直接访问。例如,视图可能包含OrderId,但要实际获取订单聚合根,您必须在 存储库上调用方法。
跨越多个聚合的视图是完全可以接受的,因为您无法使用该视图实际修改任何内容。对基础状态的更改仍然通过聚合根,这提供了一致性保证。
该视图表示数据的陈旧快照。消费者不应该期望它能够神奇地更新 - 如果你想要更新的东西,请回到存储库获取新的副本。