英文:
AutoMapper: What is the difference between CreateMap and CreateProjection?
问题
我正在寻找有关AutoMapper中CreateMap/CreateProjection和ProjectTo/MapTo之间差异的解释。我刚刚开始使用这个库,很难理解在何时使用什么。我部分理解ProjectTo与LINQ有一些关联,可以用于整个集合?我希望在Blazor Server Side项目中使用这个库。
我还在研究这两个库,因为我正在使用EF Core:
- https://github.com/AutoMapper/AutoMapper.Collection
- https://github.com/AutoMapper/AutoMapper.Collection.EFCore
但由于我对该库还很陌生,我认为最好先从基础开始。
英文:
I am looking for an explanation of the difference between CreateMap/CreateProjection in automapper and ProjectTo/MapTo by relation.
I just got started with the library and I am having trouble understanding what to use when. I partially understand that ProjectTo has some relation to LINQ and can be used for entire collections? I wish to use this library in a Blazor Server Side project.
I am also looking into these two libraries as I am using EF Core:
- https://github.com/AutoMapper/AutoMapper.Collection
- https://github.com/AutoMapper/AutoMapper.Collection.EFCore
But as I am new to the library I think it is a good idea to start with the base first before moving on.
答案1
得分: 8
以下是翻译好的内容:
TL;DR
如果你不使用 Map
,而是使用 ProjectTo
,你应该使用 CreateProjection
而不是 CreateMap
。这样,你将只使用 ProjectTo
支持的 API 子集,并且启动速度会更快。
CreateProjection
明确禁用了 Map
。CreateMap
允许两者都使用。
所以,如果你只需要通过 ORM(如Entity Framework)进行实体到DTO的映射,然后使用 ProjectTo
,那么请使用 CreateProjection
,否则请使用 CreateMap
。
Details
如文档中所述,如果你正在使用基于 IQueryable
的ORM,你可以使用 ProjectTo
,这样AutoMapper+ORM组合可以生成适当的SQL语句,而不是将整个实体加载到内存中(如果你不是一对一地进行映射,这对性能可能有积极的影响),然后在客户端进行映射:
var configuration = new MapperConfiguration(cfg =>
cfg.CreateProjection<OrderLine, OrderLineDTO>()
.ForMember(dto => dto.Item, conf => conf.MapFrom(ol => ol.Item.Name)));
public List<OrderLineDTO> GetLinesForOrder(int orderId)
{
using (var context = new orderEntities())
{
return context.OrderLines.Where(ol => ol.OrderId == orderId)
.ProjectTo<OrderLineDTO>(configuration).ToList();
}
}
.ProjectTo<OrderLineDTO>()
将告诉AutoMapper的映射引擎向 IQueryable
发出一个select子句,该子句将通知Entity Framework只需要查询Item表的Name列,就像你手动将你的 IQueryable
投影到一个带有 Select
子句的 OrderLineDTO
一样。
由于 ProjectTo
的性质,它在实际映射/操作方面要受到更多限制(并非所有内容都可以转化为SQL)。
阅读更多:
- IQueryable
和 IEnumerable 之间有什么区别? - 定义
CreateProjection
和CreateMap
CreateProjection
明确禁用Map
。CreateMap
允许两者都使用。 - 11.0 升级指南:
如果你不使用Map
,只使用ProjectTo
,你应该使用CreateProjection
而不是CreateMap
。这样,你将只使用ProjectTo
支持的API子集,启动速度会更快。 - 12.0 升级指南
你也不能为同一映射/成员分别配置Map
和ProjectTo
。 - AutoMapper ConvertUsing 未被调用
英文:
TL;DR
> If you don’t use Map
, just ProjectTo
, you should use CreateProjection
instead of CreateMap
. That way you’ll use only the API subset supported by ProjectTo
and start-up should be faster.
> CreateProjection
explicitly disables Map
. CreateMap
allows both.
So if you need only entity -> DTO mapping via ORM (like Entity Framework) and ProjectTo
then use CreateProjection
, otherwise use CreateMap
.
Details
As written in the docs if you are working with ORM based on IQueryable
you can use ProjectTo
so the AutoMapper+ORM pair can generate a proper SQL statement instead of fetching the whole entity into memory (if your are not mapping in one-to-one fashion this can have positive effect on performance) and mapping it client side:
var configuration = new MapperConfiguration(cfg =>
cfg.CreateProjection<OrderLine, OrderLineDTO>()
.ForMember(dto => dto.Item, conf => conf.MapFrom(ol => ol.Item.Name)));
public List<OrderLineDTO> GetLinesForOrder(int orderId)
{
using (var context = new orderEntities())
{
return context.OrderLines.Where(ol => ol.OrderId == orderId)
.ProjectTo<OrderLineDTO>(configuration).ToList();
}
}
> The .ProjectTo<OrderLineDTO>()
will tell AutoMapper’s mapping engine to emit a select clause to the IQueryable
that will inform entity framework that it only needs to query the Name column of the Item table, same as if you manually projected your IQueryable
to an OrderLineDTO
with a Select
clause.
Due to the nature of the ProjectTo
it is much more limited in what it can actually map/do (not everything can be turned into SQL).
Read more:
- What is the difference between IQueryable<T> and IEnumerable<T>?
- Defining both
CreateProjection
andCreateMap
>CreateProjection
explicitly disablesMap
.CreateMap
allows both. - 11.0 Upgrade Guide:
> If you don’t useMap
, justProjectTo
, you should useCreateProjection
instead ofCreateMap
. That way you’ll use only the API subset supported byProjectTo
and start-up should be faster. - 12.0 Upgrade Guide
> You also cannot have for the same map/member separate configurations forMap
andProjectTo
. - AutoMapper ConvertUsing is not called
答案2
得分: 2
短答案是通常更好使用 CreateMap
。
CreateMap 定义了可以同时用于 MapTo
和 ProjectTo
的映射,而 CreateProjection
定义了只能与 ProjectTo
一起使用的映射,实际上禁用了 MapTo
的使用。
使用 CreateMap
将使您能够直接将内存对象和数据库查询(适用于 IQueryable
的查询)映射到您选择的对象中。
CreateProjection
可以在仅从数据库查询中进行映射时使用。
英文:
The short answer is it's generally better to use CreateMap
.
Create map defines mappings that can be used for both MapTo
and ProjectTo
whereas CreateProjection
defines mappings that only works with ProjectTo
and effectively disables the use of MapTo
.
Using CreateMap
will give you the freedom to map in-memory objects and database queries (that work with IQueryable
) directly into your chosen object.
CreateProjection
can be used if you will only be mapping straight from DB queries
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论