I have a method which returns IQueryable and in the method it calls the IQueryable.ProjectTo extension method. I am able to map fields with different names from my entity/database objects to the DTO but only when an instance of the configuration mapping is created within the method. However, when I try to inject a profile class with the same configuration mapping through IMapper, the code runs without error but the fields with different names are not mapped i.e. SellCcyRate.
I have looked through the automapper documentation and cannot see where the issue is. Would someone be able to advise?
I am using
Please find my setup below:
TradeListDtoProfile.cs
public class TradeListDtoProfile : Profile
{
public TradeListDtoProfile()
{
CreateMap<Deal, TradeListDto>()
.ForMember(dest => dest.SellCCYRate, opt => opt.MapFrom(src => src.RateValueFrom));
}
}
Startup.cs - ConfigureServices method
public void ConfigureServices(IServiceCollection services) {
services.AddAutoMapper(typeof(TradeListDtoProfile));
}
Controller.cs
public class TradeController: ControllerBase {
private readonly EfCoreContext _efCoreContext;
private readonly IMapper _mapper;
public TradeController(EfCoreContext efCoreContext, IMapper mapper) {
_efCoreContext = efCoreContext;
_mapper = mapper
}
public List < TradeListDto > RetrieveTrade() {
var tradeService = new DisplayTradesService(_efCoreContext);
return tradeService.FilterSortPage(_mapper);
}
}
DisplayTradesService.cs
public class DisplayTradesService
{
private readonly EfCoreContext _context;
public DisplayTradesService(EfCoreContext context)
{
_context = context;
}
public List<TradeListDto> FilterSortPage(SortFilterPageOptions options, IMapper mapper)
{
return _context.Deal
.AsNoTracking()
.MapTradeToDto(mapper).ToList();
}
}
TradelistDtoSelect.cs
public static class TradeListDtoSelect
{
public static IQueryable<TradeListDto> MapTradeToDto(this IQueryable<Deal> deals, IMapper mapper)
{
//var configuration = new MapperConfiguration(cfg => cfg.CreateMap<Deal, TradeListDto>()
//.ForMember(dest => dest.SellCCYRate, opt => opt.MapFrom(src => src.RateValueFrom)));
//deals.ProjectTo<TradeListDto>(configuration); // This works
return deals.ProjectTo<TradeListDto>(mapper.ConfigurationProvider); // This doesn't
}
}
You cannot mix attribute mapping with the fluent API for the same map. Remove the attribute from your DTO class.
It seems that the attribute overwritten your fluent configuration.