2012-01-14 6 views
8

O non lo sono, oppure non funziona ... Ho una singola classe Source che voglio mappare a più viste che si ereditano l'una dall'altra.Sto utilizzando correttamente la funzionalità Includi di Automapper 2.0?

Fondamentalmente la classe base è il dettaglio e la classe figlio è Modifica o Aggiorna che utilizzano tutti gli stessi dati di Dettaglio, più un paio di altri campi per gestire i propri elenchi o qualsiasi altra cosa.

Qui ci sono le mappe che sto usando:

Mapper.CreateMap<Ticket, Detail>() 
       .Include<Ticket, Update>() 
       .Include<Ticket, Edit>() 
       .ForMember(dest => dest.Priority, opt => opt.MapFrom(src => src.Priority.Code)) 
       .ForMember(dest => dest.TicketID, opt => opt.MapFrom(src => src.ID)) 
       .ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.StatusCode)) 
       .ForMember(dest => dest.Category, opt => opt.MapFrom(src => src.ProblemCategoryCode)) 
       .ForMember(dest => dest.crmBusCode, opt => opt.MapFrom(src => src.Company.crmBusCode)) 
       .ForMember(dest => dest.TeamMembers, opt => opt.MapFrom(src => src.Schedules.Where(s => s.CompleteTime == null))); 

      Mapper.CreateMap<Ticket, Update>() 
       .ForMember(m => m.Schedules, opt => opt.MapFrom(t => t.Schedules.Where(s => s.EmployeeID == Util.CurrentUserID() && s.CompleteTime == null))); 

      Mapper.CreateMap<Ticket, Edit>(); 

Poi se mi Mapper.Map (biglietto) una qualsiasi delle proprietà che utilizzano MapFrom non ottengono valutato, hanno appena finiscono con i valori che 'ho avuto se non ci fosse nessuna mappatura.

Quindi cosa c'è che non va qui?

+0

Quale versione di Automapper stai usando? – nemesv

+0

Sto usando la versione 2.0 – CodeRedick

risposta

7

Come soluzione alternativa, se non si vuole chiamare Mapper.Map due volte. È possibile spostare le mappature comuni di Detail in un metodo di estensione:

public static class MappingExtensions 
{ 
    public static IMappingExpression<Ticket, TDest> MapDetailProperties<TDest>(
     this IMappingExpression<Ticket, TDest> mapBase) where TDest : Detail 
    { 
     return mapBase 
      .ForMember(dest => dest.Priority, 
       opt => opt.MapFrom(src => src.Priority.Code)) 
      ///.... 
      .ForMember(dest => dest.TeamMembers, 
       opt => opt.MapFrom(src => src 
        .Schedules.Where(s => s.CompleteTime == null))); 
    } 
} 

e quindi utilizzare tale metodo di estensione al momento della registrazione i Ticket -> Update e Ticket -> Edit mapper:

Mapper.CreateMap<Ticket, Update>() 
    .MapDetailProperties() 
    .ForMember(m => m.Schedules, opt => opt.MapFrom(t => t.Schedules 
     .Where(s => s.EmployeeID == Util.CurrentUserID() && 
      s.CompleteTime == null))); 

Mapper.CreateMap<Ticket, Edit>() 
    .MapDetailProperties(); 

quindi è possibile utilizzare Mappa normalmente:

Ticket ticket = new Ticket();  
var edit = Mapper.Map<Ticket, Edit>(ticket); 
var update = Mapper.Map<Ticket, Update>(ticket); 
+1

Un po 'più di lavoro, ma sicuramente sembra essere la strada giusta da percorrere! Sono l'unico a pensare che sarebbe più sensato per Includi comportarsi come questo metodo di estensione? – CodeRedick

+0

La soluzione al mio problema simile era leggermente diversa da questa, ma utilizza il concetto centrale di un metodo di estensione statica. Vorrei che AutoMapper supportasse questo fuori dalla scatola e spero che lo faranno in futuro. –

5

Sto utilizzando correttamente la funzionalità Includi di Automapper 2.0?

No - Quando si utilizza .Include, automapper si aspetta che le classi di destinazione sono in una gerarchia simile a classi di origine (Questo è discusso meglio here). In altre parole, se si eseguisse il mapping a diverse sottoclassi di Ticket a Detail, Update e Edit, sarebbe opportuno utilizzare Include.

Questo non sembra utile nel tuo caso. Raccomanderei di utilizzare il sovraccarico di .Map che accetta un oggetto esistente e lo modifica. In questo modo, è sufficiente definire una mappatura per il tipo base:

Ticket ticket = new Ticket(); 
Edit edit = new Edit(); 

Mapper.Map<Ticket, Detail>(ticket, edit); 
// Edit has now been automapped using the base mapping. 

Mapper.Map<Ticket, Edit>(ticket, edit); 
// The properties unique to Edit have now been mapped. 
Problemi correlati