Home > Back-end >  Automapper: How to convert a list of ids to a list of objects
Automapper: How to convert a list of ids to a list of objects

Time:09-21

I want to convert an array of ids from a dto to a list of related objects using AutoMapper, however, the mapping only works one way.

The current setup is the following:

public class Group
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Location> Locations { get; set; }
}

public class GroupDto
{
    public int id { get; set; }
    public string name { get; set; }
    public int[] locationIds { get; set; }
}

And the code in the GroupProfile:

CreateMap<Group, GroupDto>()
    .ForMember(dest => dest.id, opt => opt.MapFrom(src => src.Id))
    .ForMember(dest => dest.name, opt => opt.MapFrom(src => src.Name))
    .ForMember(dest => dest.locationIds, opt => 
        opt.MapFrom(src => src.Locations.Select(l => l.Id).ToArray()));

This code works when I try to convert a Group to a GroupDto, but not when I try it the other way around. The following error occurs:

An unhandled exception has occurred while executing the request. AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
Mapping types: GroupDto -> Group

Also, when I do it without the AutoMapper like below, it just works:

Group group = new Group
{
    Name = groupDto.name,
    Locations = _context.Locations
        .Where(l => groupDto.locationIds.Contains(l.Id))
        .ToList()
};

Help is appreciated!

CodePudding user response:

AutoMapper cannot convert an int[] to a ICollection<Location>. You need to create a seperate mapping for this.

CreateMap<GroupDto, Group>()
    .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.id))
    .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.name))
    .ForMember(dest => dest.Locations, opt => opt.MapFrom(src => src.Select(l => new Location { Id = src }));

I haven't tested this snippet so I hope you get the gist of it.

CodePudding user response:

Your AutoMapper doesn't find the mapping from GroupDto to Group.

  1. You need .ReverseMap() to support reverse mapping from Group to GroupDto.

  2. Mapping configuration for mapping from Location to int and vice versa via .ConstructUsing().

  3. Modify the mapping for the member locationIds.

  4. The mapping for the members id and name may be omitted as AutoMapper will perform the mapping between members by ignoring case-sensitive.

CreateMap<Location, int>()
    .ConstructUsing(src => src.Id);
            
CreateMap<int, Location>()
    .ConstructUsing(src => new Location { Id = src });
            
CreateMap<Group, GroupDto>()
    .ForMember(dest => dest.locationIds, opt => opt.MapFrom(src => src.Locations))
    .ReverseMap();

Demo @ .NET Fiddle

  • Related