我试图遵循干净的架构原则,当我尝试将有关持久性的实现细节保留在应用程序核心之外时:
(参考解决方案这里)
但是,我很难处理数据库查询,例如:
向我提供逾期未结订单以及客户详细信息和总价格。
因为这样的疑问
我将
OpenOrdersQuery
dto 放在应用程序核心层,但是我在哪里实现它的处理程序?
如果我在
Infrastructure
项目中实现它,我会在那里放置一些业务逻辑
我无法在应用程序核心中实现它,因为没有直接的数据访问
如果我在基础设施项目中实施它,我就会投入一些业务 逻辑在那里
其实不然。您的域模型确实负责业务逻辑(从命令端),如果这泄漏到应用程序/基础设施层,那么这就是应该解决的问题。
但是,您现在正在查看 CQRS 的查询端。理想情况下,您应该拥有一个针对用例处理(命令)优化的数据库和一个针对读取端(查询)优化的数据库。但是,作为替代,您可以使用相同的数据库进行写入和读取。我经常这样做作为第一步,然后在性能需要时迁移到读取优化的仓库和/或我清楚可以执行哪些查询以有效地设计读取端数据库。
即使使用单个数据库来执行命令和查询,我也不会使用 ORM 来执行查询。我会直接用SQL查询数据库。这可以避免您遇到的问题,即您的存储库方法(为命令设计)可能会检索与正在执行的查询无关的相关数据。
所以,总结一下:
命令管道
查询管道
是的,从一个角度来看,当没有特定的布尔值“OrderIsOpen”时,知道什么是“Open”订单可以被视为业务逻辑,但它不是命令业务逻辑(应保留在域模型中)。
在某个阶段,如果您确实设置了一个针对客户端可能执行的查询进行优化的读取数据库,那么在填充该数据库期间(在命令完成之后),您可能会考虑使用数据库中的“OrderIsOpen”字段来进行查询性能更高,并且查询处理程序无需知道哪些其他属性表明订单已打开。