2012-08-02 18 views
5

Sto provando a mappare le entità in una raccolta attraverso una tabella molti a molti utilizzando AutoMapper.AutoMapper relazione molti a molti nella raccolta

Il mio modello di dominio (Entity Framework) si presenta così:

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

Sto cercando di mappare a una classe che assomiglia a questo:

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

La mia configurazione mappatura attuale assomiglia a questo :

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

Asserire che la configurazione è valida restituisce true, ma quando provo a eseguire associare un utente a un UserDTO, ottengo: la firma del corpo e la dichiarazione in un'implementazione del metodo non corrispondono.

Se utilizzo AfterMap e si sposta manualmente su ciascuna Società nell'elenco Aziende, funzionerà, ma sembra che dovrei essere in grado di gestirlo all'interno della mappa.

Nella mia query per ottenere un singolo utente dal DB, includo la proprietà di navigazione UserCompany.Company e posso eseguire lo quickwatch e vedere che viene restituito.

risposta

6

Non è necessario disporre della mappa esplicita nella configurazione di mapping. Si dovrebbe essere in grado di fare qualcosa di simile:

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

Avrete anche bisogno di definire una mappatura per UserCompany:

Mapper.CreateMap<UserCompany, CompanyDTO>(); 

Si noti che non si dispone di una classe CompanyDTO nei tuoi esempi così ho impossibile determinare la configurazione di mappatura effettiva.

Aggiornamento

presumo ci sia un motivo per cui è necessario un IList nella tua entità utente piuttosto che semplicemente un IList. Dato che, credo che hai bisogno di una risoluzione personalizzato: https://github.com/AutoMapper/AutoMapper/wiki/Custom-value-resolvers

Update 2

Sono contento che avete ordinato. Per completezza, ecco l'esempio se decidi di utilizzare un ValueResolver personalizzato con le classi sopra.

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

Dove CompanyResolver è qualcosa di simile

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

ho provato quello che lei ha suggerito, ma il risultato era lo stesso. UserCompany è un'entità che unisce User e Company, quindi per mappare UserCompany in Company ho dovuto mappare esplicitamente ogni campo, ovvero Mapper.CreateMap () . ForMember (dto => dto.Name, opt => opt.MapFrom (x => x.Company.Name); In aggiunta a ciò ho provato a rimuovere la mia linea mappando gli oggetti IList of Company e sto ancora vedendo lo stesso errore. –

+0

Inoltre ho provato a cambiare il mio MapTo a questo : .ForMember (dto => dto.Companies, opt => opt.MapFrom (x => x.UserCompanies)), stesso errore –

+0

Possente, l'ho capito.Non pensavo che valesse la pena menzionarlo, ma gli oggetti Dto a cui stavo mappando erano in realtà dei tipi di interfaccia. L'errore stava accadendo quando AutoMapper stava cercando di creare un oggetto proxy per questo. Il mio codice di mappatura originale funzionava bene, con l'aggiunta di questa linea alla configurazione della mappatura. .ConstructUsing ((Func ) (x => new UserDTO())) Grazie per il vostro aiuto! –

Problemi correlati