【问题标题】:IQueryable Projection into DTO - Can automapper help in this scenario?IQueryable Projection into DTO - 在这种情况下自动映射器可以提供帮助吗?
【发布时间】:2015-10-28 15:54:24
【问题描述】:

我正在查看我刚刚加入的一个项目的一些 C# WebAPI 代码,并注意到数据访问的一般模式是这样的:

  1. 控制器直接调用存储库请求数据。控制器的返回类型是 IQueryable,其中 T 是 DTO(不是实体)
  2. 存储库使用 dbContext 选择一个或多个实体(连接等),然后使用 select 进行投影,将其内联投射到相关 DTO 的 iqueryable 中。这一切都是内联完成的,有时会占用大量代码。
  3. 这个 IQueryable 被返回给控制器,然后控制器返回数据。

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

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

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

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

谢谢!

【问题讨论】:

    标签: c# asp.net entity-framework asp.net-web-api repository-pattern


    【解决方案1】:

    AutoMapper 当然可以处理using AutoMapper.QueryableExtensions

    即使您的类和属性不是一对一映射,您也可以定义相当复杂的映射。您可以在AutoMapper Wiki 上阅读有关queryable extensions 的更多信息。

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 感谢您的回复,这是一本好书,我喜欢这个作者,虽然我很难理解他的结论,DTO 最终是如何创建贫血的域模型的?我可以在 DTO 中对我的一个或多个类进行平面表示,并且仍然保留一系列丰富的域对象。 DTO 如何脱离类本身?
      • 哦,还有一件事,我对你所说的 DTO 并不总是由我创建的意思很感兴趣?我总是创建我的 DTO,如果不是我,那是谁?你是说代码生成?我不会那样做,因为有时我的 DTO 代表两个或更多事物的结合,所以我总是自己创建它们。你能详细说明一下吗?我真的很感兴趣(不是为了煽动,而是想了解更多)
      • “并非总是由您创建”我假设客户端将数据发送到服务器,即您不是创建者而是客户端。还是客户端不向服务器发送数据?
      • 我会说 DTO 本身不会创建贫血的领域模型,但它们可能会被错误地用于创建贫血的领域模型,因为太多的业务逻辑被放在服务层或客户端而不是域模型中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-15
      • 1970-01-01
      • 2012-07-01
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      相关资源
      最近更新 更多