Automapper 다대일 맵 구성
-
21-12-2019 - |
문제
3개의 다른 클래스를 단일 DTO에 매핑하고 싶습니다. 각 속성은 소스와 대상에서 동일한 이름을 가지며 클래스는 다음과 같습니다.
- 사용자
- 후보자
- 포트폴리오
이것이 DTO이며 객체를 매핑하는 방법입니다.
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
}
나는 SO를 찾고 있었고 이 해결책을 찾았지만 방법을 얻지 못했습니다. 구성사용
그렇다면 다대일 매핑을 어떻게 해야 할까요? 해결 방법이 없다면 가능할까요?
해결책
Automapper의 Constructusing은 사용자 지정 코드에서 하나의 속성을 구축하는 데 유용합니다.귀하의 경우에는 실제로 필요하지 않습니다.개체에서 DTO로지도를 만들어야합니다.그런 다음 각 객체 인스턴스를 동일한 DTO 인스턴스에 매핑합니다.
그러나 Automapper가 대상을 완전히 지정되도록하기 위해 대상 객체의 각 속성을 정의하기 때문에 무시 한 것처럼 소스 오브젝트에 존재하지 않는 등록 정보로 각 매핑을 구성해야합니다.
CreateMap<Candidate, CandidateTextInfo>()
.ForMember(x=> x.ProfilePicture, opt => opt.Ignore())
.ForMember(...
// repeat for all destination properties not existing in source properties
.
이 시일 러 플레이트 코드가 너무 많으면 스택 오버플로에서 많은 솔루션을 탐구합니다.이 중에는 유망한 것처럼 보입니다. Automapper :"나머지를 무시하십시오 " (Robert Schroeder의 답변을보십시오)
다른 팁
이는 개체 간의 관계에 따라 크게 달라집니다.개체 간에 1:1 관계가 있는 경우(예:만약에 User
속성이 있습니다 User.Candidate
그리고 User.Portfolio
) 그러면 매핑이 쉽습니다.
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...
일대일 매핑이 없으면 직접 정리해야 합니다.
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...
그런 다음 귀하는 귀하의 계정을 생성하는 데 필요한 모든 수단을 사용할 수 있습니다. CandidateTextInfoSource
개체 간의 관계에 따라 다릅니다.예를 들어, 내가 User
컬렉션이 있어요 User.Candidates
, 그리고 Candidate
재산이 있다 Candidate.Portfolio
:-
CreateMap<User, IEnuemerable<CandidateTextInfoSource>>()
.ConstructUsing(
x => x.Candidates
.Select(y => Mapper.Map<CandidateTextInfo>(new CandidateTextInfoSource(x, y, y.Portfolio)))
.ToList());
답변이 매우 늦었다는 점에 감사드립니다. 하지만 개체 간의 관계를 추가로 지정해 주시면 보다 구체적인 매핑을 생성하는 데 도움을 드릴 수 있습니다.