在DDD中跨多个存储库查询数据

时间:2017-07-07 13:55:40

标签: domain-driven-design ddd-repositories

我在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; }
}

1 个答案:

答案 0 :(得分:1)

  

如果我想找到一个由John Doe创建的订单(多个聚合的搜索),DDD的方式是什么?

与访问聚合的方式几乎相同...

您创建一个存储库,该存储库提供(您的域中此视图/报告的名称)。它可能使用UserId作为标识报告的关键。在存储库的实现中,实现可以做任何有意义的事情 - SQL连接是一个合理的起点。

视图/报告基本上是一种值类型;它是不可变的,可以提供数据,但是没有任何方法,或者对聚合根的任何直接访问。例如,视图可能包含OrderId,但要实际获取订单聚合根,您必须在 存储库上调用方法。

跨越多个聚合的视图是完全可以接受的,因为您无法使用该视图实际修改任何内容。对基础状态的更改仍然通过聚合根,这提供了一致性保证。

该视图表示数据的陈旧快照。消费者不应该期望它能够神奇地更新 - 如果你想要更新的东西,请回到存储库获取新的副本。