2012-08-02 4 views
5

AutoMapper를 사용하여 엔티티를 여러 테이블을 통해 컬렉션으로 매핑하려고합니다.AutoMapper 많은 관계가 컬렉션으로

내 도메인 모델 (엔티티 프레임 워크)는 다음과 같습니다

public class User 
{ 
    public int UserID { get; set; } 
    public string Name { get; set; }   
    public IList<UserCompany> UserCompanies { get; set; } 
} 

public class Company 
{ 
    public int CompanyID { get; set; } 
    public string Name { get; set; } 
} 

public class UserCompany 
{ 
    public int UserCompanyID { get; set; } 
    public int UserID { get; set; } 
    public int CompanyID { get; set; } 
} 

나는이처럼 보이는 클래스에 매핑하기 위해 노력하고있어 :

public class CompanyDTO 
{ 
    public int CompanyID { get; set; } 
    public string Name { get; set; } 
} 

public class UserDTO 
{ 
    public int UserID { get; set; } 
    public string Name { get; set; } 
    public IList<CompanyDTO> Companies { get; set; } 
} 

나의 현재 매핑 구성은 다음과 같습니다 :

Mapper.CreateMap<Company, CompanyDTO>(); //works no problem 

Mapper.CreateMap<User, UserDTO>() 
    .ForMember(dto => dto.Companies, 
    opt => opt.MapFrom(x => Mapper.Map<IList<Company>, IList<CompanyDTO>>(x.UserCompanies.Select(y => y.Company).ToList()))); 

구성이 유효하다는 것을 증명하면 true를 표시하지만 작동 시키려고 할 때 사용자를 UserDTO에 매핑합니다. 본문의 서명과 메서드 구현의 선언이 일치하지 않습니다.

AfterMap을 사용하고 각 회사를 수동으로 회사 목록으로 이동하면 작동하지만지도를 만들 때 처리 할 수있을 것 같습니다.

DB에서 단일 사용자를 얻으려는 경우 UserCompany.Company 탐색 속성이 포함되어 있으므로 빠른 응답을 통해 반환되는 것을 확인할 수 있습니다.

답변

6

매핑 구성에 명시적인지도가 필요하지 않습니다.

Mapper.CreateMap<UserCompany, CompanyDTO>(); 

주 당신은 내가 귀하의 예에서 CompanyDTO 클래스가 없습니다 : 당신은 또한 UserCompany에 대한 매핑을 정의해야합니다

Mapper.CreateMap<User, UserDTO>() 
    .ForMember(dto => dto.Companies, opt => opt.MapFrom(x => x.UserCompanies)); 

: 당신은 같은 것을 할 수 있어야 실제 매핑 구성을 결정할 수 없습니다.

업데이트

난 당신이 단순히 IList의보다 오히려 사용자 개체에 IList의 필요 이유가 추정. 2

는 당신이 그것을 정렬이 기뻐 https://github.com/AutoMapper/AutoMapper/wiki/Custom-value-resolvers

업데이트 : 감안할 때, 난 당신이 사용자 지정 해결이 필요 믿습니다. 완전성을 위해 위의 클래스를 사용하여 사용자 지정 ValueResolver를 사용하기로 결정한 경우 예제를 들어 봅니다. CompanyResolver 난 당신이 제안하지만 결과는 동일 어떤 시도

public class CompanyResolver : ValueResolver<User, IList<CompanyDTO>> 
{ 
    protected override IList<CompanyDTO> ResolveCore(User source) 
    { 
     return source.UserCompanies 
      .Select(userCompany => 
        Mapper.Map<Company, CompanyDTO>(companies.FirstOrDefault(x => x.CompanyID == userCompany.CompanyID))) 
      .ToList(); 
    } 
} 
+0

같은이

Mapper.CreateMap<Company, CompanyDTO>(); Mapper.CreateMap<User, UserDTO>() .ForMember(dto => dto.Companies, opt => opt.ResolveUsing<CompanyResolver>()); Mapper.AssertConfigurationIsValid(); 

. UserCompany는 User와 Company를 조인하는 엔터티이므로 UserCompany를 Company에 매핑하려면 각 필드를 명시 적으로 매핑해야합니다. 즉, Mapper.CreateMap () .ForMember (dto => dto.Name, opt => opt.MapFrom (x => x.Company.Name); 그 외에도 Company 객체의 IList를 매핑하는 줄을 제거하려고했지만 여전히 동일한 오류가 표시됩니다. –

+0

또한 MapTo를 다음과 같이 전환 해 보았습니다. : .ForMember (dto => dto.Companies, opt => opt.MapFrom (x => x.UserCompanies)), 동일한 오류 –

+0

마이티, 알아 냈습니다.나는 언급할만한 가치가 있다고 생각하지는 않았지만, 실제로 매핑 된 Dto 객체는 실제로 인터페이스 유형이었다. AutoMapper가 프록시 객체를 만들려고 할 때 오류가 발생했습니다. 필자의 원래 매핑 코드는 매핑 설정에이 행을 추가하여 정상적으로 작동했습니다. .ConstructUsing ((Func ) (x => 새 UserDTO())) 도움 주셔서 감사합니다! –

관련 문제