简体   繁体   English

IQueryable 投影到 DTO - 在这种情况下自动映射器可以提供帮助吗?

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

I'm looking at some C# WebAPI code for a project I just got brought onto and notice the general pattern is like this for data access:我正在查看我刚刚进入的项目的一些 C# WebAPI 代码,并注意到数据访问的一般模式是这样的:

  1. The controller makes a call directly to a repository asking for data.控制器直接调用存储库请求数据。 The controller's return type is IQueryable where T is a DTO (not an entity)控制器的返回类型是 IQueryable,其中 T 是 DTO(不是实体)
  2. The repository uses dbContext to select one or more entities (joins, etc) and then does a projection using select to cast it inline into an iqueryable of the relevant DTO.存储库使用 dbContext 来选择一个或多个实体(连接等),然后使用 select 进行投影以将其内联转换为相关 DTO 的 iqueryable。 This is all done inline and sometimes it takes up quite a lot of lines of code.这一切都是内联完成的,有时会占用相当多的代码行。
  3. This IQueryable is returned to the controller, who then returns the data back out.这个 IQueryable 返回给控制器,然后控制器返回数据。

So I'm concerned about a few things here.所以我担心这里的一些事情。 For one, shouldn't something like AutoMapper be used to handle this so each specific repository isn't flooded with these rather large projections from one (or several) entities to one DTO?一方面,难道不应该使用 AutoMapper 之类的东西来处理这个问题,这样每个特定的存储库就不会被这些从一个(或多个)实体到一个 DTO 的相当大的投影所淹没?

Again, keep in mind most of the time, it's not one entity (ie User -> UserDto) but several entities mapping to one flattened DTO.同样,在大多数情况下,请记住,它不是一个实体(即 User -> UserDto),而是映射到一个扁平 DTO 的多个实体。 So for example Class1, Class2, Class3, Class4 all map to AggregatedClassDto.因此,例如 Class1、Class2、Class3、Class4 都映射到 AggregatedClassDto。 Should this be done in the repository layer at all, and if so, is Automapper appropriate in this case?这是否应该在存储库层中完成,如果是这样,Automapper 在这种情况下是否合适?

If I move the mapping logic out somewhere else, I think it's all going to be custom (almost nothing from a property/field perspective translates 1-1).如果我将映射逻辑移出其他地方,我认为这一切都将是自定义的(从属性/字段的角度来看,几乎没有任何内容可以转换为 1-1)。 Doesn't that just move all the code to lots of custom converters or something?这不是将所有代码移动到许多自定义转换器或其他东西吗?

Finally, any other areas of concern?最后,还有其他需要关注的领域吗?

Thanks!谢谢!

AutoMapper can certainly handle that using AutoMapper.QueryableExtensions . AutoMapper 当然可以using AutoMapper.QueryableExtensions来处理。

You can define pretty complex mappings even if your classes and properties don't map one-to-one.即使您的类和属性不是一对一映射,您也可以定义非常复杂的映射。 You can read more about queryable extensions on the AutoMapper Wiki .您可以在AutoMapper Wiki上阅读有关queryable extensions更多信息

As far as having the mappings done inside the repository, speaking from a single-responsibility point of view, you probably shouldn't perform mappings inside your repository and return entities instead.至于在存储库内完成映射,从single-responsibility角度来看,您可能不应该在存储库内执行映射并返回实体。

I'm adding this as a separate answer since I do not fully agree with the first answer.我将此作为单独的答案添加,因为我不完全同意第一个答案。

I agree on the point that mappings should not be done inside the repository, but I do not agree that all mappings should be done by AutoMapper since there is a conceptual difference between a DTO and an object , being that a DTO is a data transfer object and strictly speaking isn't always created by you, and therefore should not be trusted.我同意映射不应在存储库内完成的观点,但我不同意所有映射都应由AutoMapper完成,因为DTOobject之间存在概念差异,即DTO是数据传输对象并且严格来说并不总是由您创建,因此不应该被信任。 In my experience it is better to convert DTOs to POCOs manually rather than automap them (the other way, sure, go ahead).根据我的经验,最好手动将DTOs转换为POCOs ,而不是自动POCOs它们(当然,另一种方式是继续)。 This blog-post quite well describes my opinion on the matter. 这篇博文很好地描述了我对此事的看法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM