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:
But as I am new to the library I think it is a good idea to start with the base first before moving on.
TL;DR
If you don’t use
Map
, justProjectTo
, you should useCreateProjection
instead ofCreateMap
. That way you’ll use only the API subset supported byProjectTo
and start-up should be faster.
CreateProjection
explicitly disablesMap
.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 theIQueryable
that will inform entity framework that it only needs to query the Name column of the Item table, same as if you manually projected yourIQueryable
to anOrderLineDTO
with aSelect
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:
CreateProjection
and CreateMap
CreateProjection
explicitly disablesMap
.CreateMap
allows both.
If you don’t use
Map
, justProjectTo
, you should useCreateProjection
instead ofCreateMap
. That way you’ll use only the API subset supported byProjectTo
and start-up should be faster.
You also cannot have for the same map/member separate configurations for
Map
andProjectTo
.