Domain driven design DDD-在单个存储库方法中查询多个聚合的自定义SQL如何?

Domain driven design DDD-在单个存储库方法中查询多个聚合的自定义SQL如何?,domain-driven-design,ddd-repositories,Domain Driven Design,Ddd Repositories,我设计聚合以强制执行不变量和业务规则。我总是把我的聚合看作是一个“写模型”/“事务模型”。 考虑到这一点,我总是可以在我的存储库中使用自定义SQL/Linq公开“复杂”的GET方法,因为我不是在替换数据 例如,考虑两个虚构的聚合根(学生和学校),只使用它们之间的引用ID。如果我想向一所学校的所有学生发送电子邮件,我通常会使用一个域服务来执行此操作,以提高性能: 使用类似“GetAllStudenteMailAddresssForSchool(Guid schoolId)”的方法调用存储库 为每个

我设计聚合以强制执行不变量和业务规则。我总是把我的聚合看作是一个“写模型”/“事务模型”。 考虑到这一点,我总是可以在我的存储库中使用自定义SQL/Linq公开“复杂”的GET方法,因为我不是在替换数据

例如,考虑两个虚构的聚合根(学生和学校),只使用它们之间的引用ID。如果我想向一所学校的所有学生发送电子邮件,我通常会使用一个域服务来执行此操作,以提高性能:

  • 使用类似“GetAllStudenteMailAddresssForSchool(Guid schoolId)”的方法调用存储库
  • 为每个学生发送一封电子邮件
  • 当然,存储库实现需要对这两个聚合执行“复杂”查询(联接)

    典型的替代方法是在域服务中对存储库执行多个调用:

  • 从学校档案馆取学校
  • 对于该校的每位学生,称为IStudentRepository
  • (当然,这取决于聚合模型化,但基本概念仍然存在)

    关于这一点,我与同事们进行了很多辩论,许多人认为第一种方法会将域业务泄漏到域之外(即在基础架构层,在存储库实现中)

    对我来说,这是一种简单的过滤策略,就像ISchoolRepository公开“GetSchoolsFromCity(Guid cityId)”这样的方法一样。过滤发生在单个聚合而不是两个聚合上,这一事实不会改变任何事情


    对此有什么意见吗?

    首先,不要对让聚合进行交互的完美方式感到非常困扰。通常没有单一的正确答案,只有一堆错误的答案


    其次,您描述了聚合和存储库,但没有描述有界上下文。从我对学校的了解来看,很难有一所没有学生的学校。你是怎么做的


    最后,正如你所说,这是阅读模型的东西。使用LINQ查询获取给定学校的所有学生电子邮件是非常好的。将结果输入到发送电子邮件的服务中并继续执行。

    在实现查询时,您不必使用域模型,即聚合。您可以查询数据库,并根据所需数据将所需数据提取到普通自定义dto中。通过这种方式,您可以隔离写入模型和resd模型

    “从我对学校的了解来看,很难有一所没有学生的学校。你是如何建立这种模式的?”事实上,这纯粹是我为我的问题在飞行中发明的一个场景。也许这不是一个完美的例子……您可能会发现,当您突然有20种不同的方法重载来读取存储库中的聚合时,这种方法将使您陷入困境。