我应该从存储库返回什么?

问题描述 投票:0回答:2

是否应该始终从存储库返回模型,或者我可以从 ASP.NET Core Web API 返回 DTO 吗?

在我的应用程序中,我需要返回DTO,但我觉得这种行为是不正确的。经过搜索,我发现了很多意见

c# web-services .net-core asp.net-core-webapi
2个回答
0
投票

“存储库”和“存储库模式”之间存在常见的混淆。

首先让我们回到存储库的定义:

存储库在域和数据映射层之间进行中介,就像内存中的域对象集合一样。 (...) 可以在存储库中添加和删除对象,就像从简单的对象集合中添加和删除对象一样,存储库封装的映射代码将在幕后执行适当的操作。

来源:企业应用程序架构模式,Martin Fowler,2002 年

因此,传统上存储库必须返回域对象。

从技术上讲,存储库通常是使用存储库设计模式实现的类。存储库模式是通过提供一个与

ICollection<T>
(添加、列表、更新、删除等)类似的接口来实现的,但实际上是在幕后访问持久性存储。该模式被称为“存储库模式”,因为这种模式最初是在存储库中实现的,但它也可以在应用程序的其他层中实现。

⚠️ 请注意,这些概念是在 ORM 库尚未像今天这样广泛使用的时代形成的。当时,大多数开发人员都会在存储库中实现手动对象到 SQL 的转换。存储库中读取操作的目的是从存储中重新获取当前状态,以便应用程序可以决定命令(状态更改用例)是成功还是失败。对于查询(只读用例),强烈建议实现单独的类来执行 SQL 到 DTO 的直接转换,与在存储库顶部添加另一层转换相比,这明显提高了性能。尽管部分实现了 repository 模式,但这些类不被称为 repositories,因为它们不返回域对象。常见的名称包括演讲者调解者

实体框架等现代 ORM 库模糊了界限,因为工程师对于

DbContext
(或更具体地说
DbSet<T>
)是否构成存储库以及 ef 实体是否可以作为域对象进行操作,或者是否可以进行操作有一系列意见。 ef 实体被视为持久层实现细节,您必须将其转换为“真实”业务层中的另一个模型。然而,库中最近的变化表明,人们不断关注消除前一种方法的障碍:2023 年 4 月就应用程序单元测试策略发布了强有力的公告,增加了对值对象的支持,...

根据您对该主题的看法,您可能会实现介于两个极端之间的任何内容:

  • DbSet<T>
    视为存储库,将实体视为域对象,将 efcore lib 视为持久层,将 aspnet 视为表示层。您在控制器中实现业务规则,使用您自己的代码或映射库将实体转换为 DTO;

  • 将整个

    DbContext
    视为持久层实现细节,将控制器视为表示层实现细节。如果您需要具有专用模型的适当域层,那么您必须处理 efcore 实体到域转换以及 efcore 实体到 DTO 转换,以及存储库、演示者、服务等...



0
投票

ASP.NET Core Web API 中的典型层是:

  • 控制器 - 负责 HTTP 请求和响应
  • 服务 - 负责领域逻辑
  • Repository - 负责数据访问

通常,从数据库实体到域类或 DTO 的任何转换都将发生在服务层,而不是存储库。

是否应该将数据库实体映射到其他东西是一个观点问题,并且可能取决于整体解决方案的复杂性,特别是 Web API 的使用者是否位于您正在构建的解决方案的外部。

© www.soinside.com 2019 - 2024. All rights reserved.