IQueryable Projection into DTO - automapper 可以在这种情况下提供帮助吗?

IQueryable Projection into DTO - Can automapper help in this scenario?

我正在查看我刚刚参与的项目的一些 C# WebAPI 代码,并注意到数据访问的一般模式如下所示:

  1. 控制器直接调用存储库请求数据。控制器的 return 类型是 IQueryable,其中 T 是 DTO(不是实体)
  2. 存储库使用 dbContext 到 select 一个或多个实体(连接等),然后使用 select 进行投影以将其内联投射到相关 DTO 的可查询对象中。这都是在线完成的,有时会占用很多代码行。
  3. 这个 IQueryable 被 return 发送到控制器,然后控制器 return 返回数据。

所以我担心这里的一些事情。其一,难道不应该使用像 AutoMapper 这样的东西来处理这个问题,这样每个特定的存储库就不会充斥着从一个(或多个)实体到一个 DTO 的这些相当大的投影吗?

再次提醒,大多数时候请记住,它不是一个实体(即 User -> UserDto),而是映射到一个扁平化 DTO 的多个实体。因此,例如 Class1、Class2、Class3、Class4 都映射到 AggregatedClassDto。这是否应该在存储库层完成,如果是这样,Automapper 在这种情况下是否合适?

如果我将映射逻辑移到其他地方,我认为这一切都将是自定义的(从 property/field 的角度来看,几乎没有任何东西可以翻译 1-1)。这不就是将所有代码移动到许多自定义转换器或其他东西吗?

最后,还有其他需要关注的地方吗?

谢谢!

AutoMapper can certainly handle that using AutoMapper.QueryableExtensions.

即使您的 类 和属性不是一对一映射,您也可以定义非常复杂的映射。您可以在 AutoMapper Wiki.

上阅读有关 queryable extensions 的更多信息

就在存储库内完成映射而言,从 single-responsibility 的角度来看,您可能不应该在存储库和 return 实体内执行映射。

我将此添加为单独的答案,因为我不完全同意第一个答案。

我同意映射不应在存储库内部完成这一点,但我不同意所有映射都应由 AutoMapper 完成,因为 DTO 之间存在概念差异和一个 object,因为 DTO 是一个数据传输对象,严格来说并不总是由您创建,因此不应该被信任。根据我的经验,最好手动将 DTOs 转换为 POCOs 而不是自动映射它们(当然,另一种方式继续)。 This blog-post quite well describes my opinion on the matter.