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

Domain driven design 在DDD中跨多个存储库查询数据,domain-driven-design,ddd-repositories,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 User

我在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(seach accross multiple aggregates)创建的订单,DDD的方式是什么

  • 将First_Name和Last_Name添加到OrderAggregate中,以便在OrderRespository中添加FindByUserFirstLastName方法,但这可能会引起两个聚合根之间的数据一致性问题

  • 创建原始sql查询并直接访问数据库,以便跨越“存储库”中的搜索帐户

  • 使用“查找器”直接从数据库连接实体

  • 将完成查询所需的数据复制到新的聚合根目录,如


如果我想找到John Doe(seach accross multiple aggregates)创建的订单,DDD的方式是什么

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

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

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

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

该视图表示数据的过时快照。消费者不应该期望它神奇地更新——如果您想要更新的东西,请返回存储库获取新副本

如果我想找到John Doe(seach accross multiple aggregates)创建的订单,DDD的方式是什么

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

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

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

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


该视图表示数据的过时快照。消费者不应该期望它神奇地更新——如果您想要更新的内容,请返回存储库获取新副本。

不要让数据库模型支配您的域模型您有两个有界上下文:排序和UserManagement@ConstantinGALBENU不,这只是错误的解释,如果你确定(而且只有你能)如果您只有一个有界上下文(只有一个普遍存在的语言边界),那么您不应该基于查询需求(读取模型)对聚合(写入模型)进行建模。因此,在这种情况下,在不使用CQR的情况下,您应该使用选项2或3。如果您使用CQR,那么您只需要构建一个新的读取模型,该模型包含查询所需的所有信息,在不使用任何
连接的情况下
不要让数据库模型支配您的域模型您有两个有界上下文:排序和UserManagement@ConstantinGALBENU不,如果您确信(并且只有您能够)您只有一个有界上下文(只有一个普遍存在的语言边界),那么这就是错误的解释然后,您不应该基于查询需求(读取模型)对聚合(写入模型)建模。因此,在这种情况下,在不使用CQR的情况下,您应该使用选项2或3。如果您确实使用CQR,那么您只需要构建一个新的读取模型,该模型包含查询所需的所有信息,而不使用任何
联接
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; }
}