Automapper Muitos-para-um mapa de configuração
-
21-12-2019 - |
Pergunta
Eu quero o mapa 3 classes diferentes em um único DTO, cada propriedade tem o mesmo nome sobre a origem e o destino, as classes são as seguintes:
- Utilizador
- Candidato
- Carteira de
este é o DTO e como eu quero mapa meus objetos:
public class CandidateTextInfo
{
public string ProfilePicture { get; set; } //-->User
public ObjectId UserId { get; set; } //-->User
public string Name { get; set; } //--> Candidate
public string Headline { get; set; } //--> Candidate
public Gender Gender { get; set; } //--> Candidate
public byte Rating { get; set; } //--> Candidate
public bool IsCompany { get; set; } //--> Candidate
public string[] Tags { get; set; } //--> Portafolio
public string[] Categories { get; set; } //--> Portafolio
public string ExecutiveSummary { get; set; } //--> Portafolio
public HourlyRate HourlyRate{ get; set; } //--> Candidate
}
Eu estive olhando ASSIM e achei esta solução, mas eu não entendo o método ConstructUsing
então, como posso fazer para ter um muitos-para-um mapeamento, é que isso é possível, se não qualquer solução?
Solução
Automapper do ConstructUsing é útil para construir um imóvel de código personalizado.No seu caso, não é realmente necessário.Você só precisa criar os mapas de seus objetos para o seu DTO.Em seguida, o mapa de cada instância de objeto para o mesmo DTO instância.
No entanto, desde Automapper quer que cada propriedade do objeto de destino para ser definido, a fim de garantir que o destino é totalmente especificado, você precisará configurar cada mapeamento com as propriedades não existentes no objecto de origem de tão ignorados
CreateMap<Candidate, CandidateTextInfo>()
.ForMember(x=> x.ProfilePicture, opt => opt.Ignore())
.ForMember(...
// repeat for all destination properties not existing in source properties
Se isto é muito clichê código, muitas soluções são exploradas no estouro de pilha, entre os quais este parece promissor: AutoMapper:"Ignorar o resto"? (olhar para Robert de Schroeder resposta)
Outras dicas
Isso depende muito do relacionamento entre os objetos.Se você tem uma relação de 1:1 entre os objetos (por exemplo,se User
tem propriedades User.Candidate
e User.Portfolio
) em seguida, o mapeamento é fácil:-
CreateMap<User, CandidateTextInfo>()
.ForMember(d => d.ProfilePicture, o => o.MapFrom(s => s.ProfilePicture)
// ...
.ForMember(d => d.Name, o => o.MapFrom(s => s.Candidate.Name)
// And so on...
Se você não tem um, um-para-um mapeamento, você precisa para organizar um pouco as coisas, a si mesmo:-
public class CandidateTextInfoSource
{
public CandidateTextInfoSource(User user,
Candidate candidate,
Portafolio portafolio)
{
this.User = user;
this.Candidate = candidate;
this.Portafolio = portafolio;
}
public User User { get; set; }
public Candidate Candidate { get; set; }
public Portafolio Portafolio { get; set; }
}
// ...
CreateMap<CandidateTextInfoSource, CandidateTextInfo>()
.ForMember(d => d.ProfilePicture, o => o.MapFrom(s => s.User.ProfilePicture)
// ...
.ForMember(d => d.Name, o => o.MapFrom(s => s.Candidate.Name)
// And so on...
Em seguida, você pode usar o que significa que você precisa para criar o seu CandidateTextInfoSource
dependendo da relação entre os objetos.Por exemplo, se eu suponha que um User
tem uma coleção User.Candidates
, e um Candidate
tem uma propriedade Candidate.Portfolio
:-
CreateMap<User, IEnuemerable<CandidateTextInfoSource>>()
.ConstructUsing(
x => x.Candidates
.Select(y => Mapper.Map<CandidateTextInfo>(new CandidateTextInfoSource(x, y, y.Portfolio)))
.ToList());
Agradeço que esta resposta é muito tarde, mas se você especificar a relação entre os objetos, eu posso ajudar você a criar um mapeamento específico.