【发布时间】:2016-02-01 12:34:54
【问题描述】:
在此处进行一些 C# 代码审查,并注意到开发人员正在与 5 个额外的表进行连接,并将内联 IQueryable 投影到 DTO。在存储库中加入的表是 User、Appointment、CommunicationPreference、UserProduct 和 Product。我没有设计这个系统,我可能会稍微简化它,但让我们现在就这样吧。使用实体框架和 Web API。
这有点长,所以我很抱歉,但真的很想听听其他人对此事的看法。
因此,这些表的相关性在于,每个用户都有一个即将到来的服务预约列表来服务他们的产品。 UserProduct 表显示产品和用户之间的关系,产品表显示产品的种类。 CommunicationPreference 处理他们希望如何联系他们,例如他们的服务到期时间、是否有人来为产品提供服务、他们希望如何联系(电话电子邮件文本等)。
因此,开发人员在存储库本身中将这些表连接在一起,然后创建一个名为“UserServiceOverviewDto”的 DTO,该 DTO 返回到控制器,然后返回到前端,基本上有信息以网格形式显示给客户代表(谁用户是,即将到来的约会,什么产品等等,基本上都是我上面写的)。
我理解他们这样做的原因 - 他们不是对 5 个不同的存储库进行 5 次调用,而是一次性完成所有操作,然后不必将每个存储库都转换为 DTO,而是一次性完成所有操作。但我知道存储库也不应该返回 DTO。理想情况下,您的存储库应该返回在逻辑上聚合并代表解决您问题的一个实体的内容。
当我在思考这个问题时,我在 SO What type to return when querying multiple entities in Repository layer? 中偶然发现了这个问题,但它对我的帮助并不大,我想就如何做寻求更多建议。
从 DDD 的角度来看,我想知道需要引入什么新“事物”。也许我需要创建一个新的上下文/存储库,这是这个新事物。如果我想说这是一个常见的分组并给它起一个像“X”这样的名字,这是否意味着我想创建一个新的数据库表来表示它?可能不会,因为我已经有了存储这些信息的表。
这是否意味着我想创建一个名为“X”的新类而没有相应的数据库表?那么这与 DTO 有什么不同呢?事实上,它几乎表明,通过创建这个类,我试图通过实例化 X 而不是 XDto 来使我的存储库更加纯粹,然后无论如何将 X 转换为服务层中的 DTO(除了转移之外,我没有任何收获周围的东西并创建一个非常贫血的实体)。
总之,问题是:
如果我有多个实体,为了在前端方便而将它们组合在一起,是否更好:
- 服务层是否进行了 5 次不同的数据库调用,并在该层组装了一个 DTO 以返回给控制器?这不是很糟糕吗? 5 个电话只是为了让我的代码看起来更“纯粹”?一次性完成联接并从数据库中取回您需要的内容不是更好吗?
- 用C#新建一个类,代表这5个表的联姻,然后实现这个类和对应的DTO的映射。这个类不会像我上面说的那样被持久化。
- 让存储库执行其连接以创建新的 DTO 作为内联投影(似乎错误的 b/c 存储库应该返回一个实体而不是 DTO)
真的很期待这里的一些反馈!谢谢!
【问题讨论】:
标签: c# asp.net-web-api architecture domain-driven-design repository-pattern