Search code examples
c#automapperautomapper-11

Automapper's ProjectTo not playing nice with generics


Using ProjectTo with automapper and generics doesn't seem to work well. I created this mapping:

CreateMap<ChecklistSoftwareFirmware, OutputDTO>()
    .AfterMap((entity, dto) => {
        dto.ETag = "something here";
        dto.Compiler = new() {
            Name = "foo",
            Version = "bar"
        };
    })

If I do this:

var entity = await _context.Set<TEntity>()
    .AsNoTracking()
    .Where(x => x.Uid == uid)
    .ProjectTo<TOutputDTO>(_mapper.ConfigurationProvider)
    .SingleOrDefaultAsync(cancellationToken);

Where TEntity is my EF Core database model and TOutputDTO is my DTO class none of the stuff from AfterMap runs. If I instead do this, it works properly:

var entity = await _context.Set<TEntity>()
    .AsNoTracking()
    .Where(x => x.Uid == uid)
    .SingleOrDefaultAsync(cancellationToken);

var dto = _mapper.Map<TOutputDTO>(entity);

Solution

  • The documentation shows a list of what is supported by ProjectTo and what is not.

    Before and AfterMap are not supported.

    Not all mapping options can be supported, as the expression generated must be interpreted by a LINQ provider. Only what is supported by LINQ providers is supported by AutoMapper

    Supported:

    • MapFrom (Expression-based)
    • ConvertUsing (Expression-based)
    • Ignore
    • NullSubstitute
    • Value transformers
    • IncludeMembers

    Not supported:

    • Condition
    • SetMappingOrder
    • UseDestinationValue
    • MapFrom (Func-based)
    • Before/AfterMap
    • Custom resolvers
    • Custom type converters
    • ForPath
    • Value converters
    • Any calculated property on your domain object