gpt4 book ai didi

c# - 具有多个实体的存储库创建 DTO

转载 作者:太空狗 更新时间:2023-10-29 21:38:39 26 4
gpt4 key购买 nike

在此处进行一些 C# 代码审查,并注意到一名开发人员正在对 5 个额外的表进行联接,并将内联 IQueryable 投影到 DTO 中。存储库中加入的表是UserAppointmentCommunicationPreferenceUserProductProduct 。我没有设计系统,我可能会稍微简化它,但让我们暂时按原样使用它。使用 Entity Framework 和 Web API。

这有点长,所以我很抱歉,但真的很想听听其他人对此事的看法。

因此,这些表的相关性在于每个用户都有一个即将到来的服务预约列表来为其产品提供服务。 UserProduct 表显示了产品与用户之间的关系,产品表显示了产品的种类。 CommunicationPreference 处理他们希望如何联系他们的事情,比如他们的服务何时到期,如果有人来服务产品,他们希望如何联系(电话电子邮件文本等)。

所以开发人员在存储库本身中将这些表连接在一起,然后创建一个名为“UserServiceOverviewDto”的 DTO 返回给 Controller ,然后返回给前端,基本上有信息要在网格中显示给客户代表(谁用户是,即将到来的约会,什么产品,等等。基本上我刚才在上面写的所有内容)。

我理解他们为什么这样做 - 他们不是对 5 个不同的存储库进行 5 次调用,而是一次完成所有操作,然后不必将每个存储库都转换为 DTO,他们一次性完成了所有操作。但我知道存储库也不应该返回 DTO。理想情况下,您的存储库应该返回在逻辑上聚合并代表解决您问题的一个实体的内容。

当我在考虑这个问题时,我在 SO What type to return when querying multiple entities in Repository layer? 中偶然发现了这个但这并不能真正帮助我,我想就如何做寻求更多建议。

从 DDD 的角度来看,我想知道需要引入什么新“事物”。也许我需要创建一个新的上下文/存储库,这是新事物。如果我想说这是一个常见的分组并给它起一个像“X”这样的名称,这是否意味着我想创建一个新的数据库表来表示它?可能不会,因为我已经有了存储这些信息的表。

这是否意味着我想创建一个没有相应数据库表的名为“X”的新类?那么这与 DTO 有什么不同呢?事实上,它几乎表明通过制作此类,我试图通过实例化 X 而不是 XDto 来使我的存储库更纯粹,然后无论如何将 X 强制转换为服务层中的 DTO(除了转移之外我没有获得任何东西周围的东西并创建一个非常贫血的实体)。

综上所述,问题是:

如果我有多个实体,为了前端的方便而组合在一起,是否更好:

  1. 让服务层进行 5 次不同的数据库调用,并在该层组装一个 DTO 以返回给 Controller ?这不是很糟糕吗? 5 个调用只是为了让我的代码看起来更“纯粹”?一次完成联接并从数据库中取回所需内容不是更好吗?
  2. 在 C# 中创建一个新类来表示这 5 个表的联姻,然后实现该类与相应 DTO 之间的映射。这个类不会像我上面说的那样被持久化。
  3. 让存储库执行其连接以创建一个新的 DTO 作为内联投影(似乎错误的 b/c 存储库应该返回一个实体而不是 DTO)

真的很期待这里的一些反馈!谢谢!

最佳答案

这个问题不是特定于 CQRS 的,在它之外也有效,所以我会这样回答。

您描述的情况在实现统计功能时经常出现。例如。回答诸如“有多少用户订购了该产品,按天分组?”之类的问题。这有时称为用例优化查询

在这些情况下,您建议的第二种方法通常是最好的。 创建一个新类型来模拟此类操作的结果。聚合存储库中的所有数据并返回该类型的实例。

解决方案 #1 通常非常效率低下,因为服务层无法使用数据库提供的聚合和分组功能。解决方案 #3 违反了单一责任原则,迟早会导致可维护性问题。

新类型的设计注意事项

  • 返回的数据始终是只读的,因此可以将类型建模为值对象
  • 如果类型在领域中有意义,就把它放在领域层。如果没有,则将其放入持久层。

关于c# - 具有多个实体的存储库创建 DTO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33463860/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com