2012-08-02 14 views
5

Estoy tratando de asignar entidades en una colección a través de una tabla de muchas a muchas utilizando AutoMapper.AutoMapper relación de muchos a muchos en la colección

Mi modelo de dominio (Entity Framework) tiene el siguiente aspecto:

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; } 
} 

Estoy intentando asignar a una clase que tiene este aspecto:

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; } 
} 

Mi configuración de la asignación actual se parece a esto :

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()))); 

Afirmando que la configuración es válida devuelve cierto, pero cuando intento activar Aliado asignar un usuario a un UserDTO, obtengo: la firma del cuerpo y la declaración en una implementación de método no coinciden.

Si utilizo AfterMap y muevo manualmente cada Compañía a la lista de Compañías, funcionará, pero parece que debería poder manejar esto dentro del mapa de creación.

En mi consulta para obtener un solo usuario de la base de datos, incluyo la propiedad de navegación UserCompany.Company y puedo hacer un chequeo rápido y ver que se devuelve.

Respuesta

6

No necesita tener el mapa explícito en su configuración de mapeo. Usted debe ser capaz de hacer algo como:

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

También tendrá que definir una asignación de UserCompany:

Mapper.CreateMap<UserCompany, CompanyDTO>(); 

Tenga en cuenta que usted no tiene una clase CompanyDTO en sus ejemplos, así que no puede determinar la configuración de mapeo real.

actualización

supongo que hay una razón por qué necesita un IList en su entidad Usuario en lugar de simplemente un IList. Teniendo en cuenta esto, creo que necesita una resolución personalizada: https://github.com/AutoMapper/AutoMapper/wiki/Custom-value-resolvers

Actualización 2

me alegro de que lo tienes solucionado. Para completar, aquí está el ejemplo si decide usar un ValueResolver personalizado con las clases anteriores.

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

Dónde CompanyResolver es algo así como

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

Probé lo que usted sugiere, pero el resultado fue el mismo. UserCompany es una entidad que se une a User y Company, por lo que para asignar UserCompany a Company tuve que mapear explícitamente cada campo, es decir, Mapper.CreateMap () .ForMember (dto => dto.Name, opt => opt.MapFrom (x => x.Company.Name); Además de eso intenté eliminar mi línea mapeando el IList de los objetos Company y sigo teniendo el mismo error. –

+0

También intenté cambiar mi MapTo a este : .ForMember (dto => dto.Companies, opt => opt.MapFrom (x => x.UserCompanies)), mismo error. –

+0

Poderoso, lo descubrí.No pensé que valiera la pena mencionarlo, pero los objetos Dto a los que estaba mapeando eran en realidad tipos de interfaz. El error estaba ocurriendo cuando AutoMapper intentaba crear un objeto proxy para él. Mi código de mapeo original funcionó bien, con la adición de esta línea a la configuración de mapeo. .ConstructUsing ((Func ) (x => new UserDTO())) ¡Gracias por su ayuda! –

Cuestiones relacionadas