简体   繁体   中英

Automapper child mapping with entity in the middle

I have the following entity structure that I want to map to a Dto

Context Entities

public class CallPoint
{
    public int Id { get; set; }
    public string Name {get; set;}
    public ICollection {UserCallPoint} UserCallPoints {get; set;}
}

public class UserCallPoint
{
    public int Id {get; set;}
    public CallPoint CallPoint {get; set;}
    public User User {get; set;
}

public class User
{
    public int Id {get; set;}
    public string Email {get; set;}
    public ICollection<UserCallPoint> UserCallPoints {get; set;
}

DTO

public class CallPointDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<UserDto> Users { get; set; }
}

public class UserDto
{
    public int Id { get; set; }
    public string Email { get; set; }
    public List<CallPointDto> CallPoints { get; set; }
}

So basically I have a many to many mapping but there is an entity in between that acts as a lookup table basically. How do I do this mapping? I am currently just looping and mapping like below but it is far too slow

    private List<CallPointDto> MapCallPoint(List<CallPoint> callPoints)
    {
        List<CallPointDto> callPointDtos = new List<CallPointDto>();
        foreach (var callPoint in callPoints)
        {
            var callPointDto = _mapper.Map<CallPointDto>(callPoint);
            callPointDto.Users = new List<UserDto>();
            foreach (var item in callPoint.UserCallPoints)
            {
                UserDto userDto = _mapper.Map<UserDto>(item.User);
                callPointDto.Users.Add(userDto);
            }
            callPointDtos.Add(callPointDto);
        }
        return callPointDtos;
    }

How would I do this with a Custom Resolver?

I can't give you the answer that you are looking for because of the problem that the n:m relation could run endlessly. But i would suggest you to work with different sub-DTOs like this:

public class CallPointBaseDto
{
    public int Id { get; set; }
    public string Name { get; set; }
}
public class CallPointDto : CallPointBaseDto
{
    public List<UserBaseDto> Users { get; set; }
}

public class UserBaseDto
{
    public int Id { get; set; }
    public string Email { get; set; }
}
public class UserDto : UserBaseDto
{
    public List<CallPointBaseDto> CallPoints { get; set; }
}

Mapping:

cfg.CreateMap<CallPoint, CallPointDto>()
    .ForMember(dest => dest.Users, opt => opt.MapFrom(src => src.UserCallPoints.Select(ucp => ucp.User)));
cfg.CreateMap<User, UserBaseDto>();

The downside of this, is of course, you don't have the CallPoints in your UserBaseDto, but if you need it, you can call this User explicitly and map it the other way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM