2013-10-23 6 views
34

Uso il mappatore automatico per mappare più oggetti (classe db in oggetti ui).Automapper - Sorgente multioggetto e una destinazione

Mappa 1:

Mapper.CreateMap<sourceone, destination>().ForMember(sss => sss.one, m => m.MapFrom(source => source.abc)); 

Mappa 2:

Mapper.CreateMap<sourcetwo, destination>().ForMember(sss => sss.two, m => m.MapFrom(source => source.xyz)); 

destination d = new destination(); 

// Mappa 1

d = AutoMapper.Mapper.Map<sourceone, destination>(sourceone); 

// Mappa 2

d = AutoMapper.Mapper.Map<sourcetwo, destination>(sourcetwo); 

Una volta chiamata alla 'Mappa 2', i valori che vengono popolati usando la Mappa 1 sono persi .. (cioè destinazione.una sta diventando vuota). Come posso risolvere questo?

risposta

54

Map ha un sovraccarico che prende una sorgente e destinazione oggetto:

d = AutoMapper.Mapper.Map<sourceone, destination>(sourceone); 

/* Pass the created destination to the second map call: */ 
AutoMapper.Mapper.Map<sourcetwo, destination>(sourcetwo, d); 
+1

Eccellente. Grazie – CoolArchTek

+6

questo è brutto e confuso, l'API dovrebbe includere chiaramente un metodo Map (params) – Filip

+1

@Flip: potrei essere frainteso cosa intendi, ma include _un metodo 'Map (params)', restituisce solo un nuovo 'T'. –

4
public class Person 
{ 
    public string Name { get; set; } 
    public string PhNo { get; set; } 
} 
public class Company 
{ 
    public int EmpNo { get; set; } 
    public string Title { get; set; } 
} 

public class PersonCompany 
{ 
    public string Name { get; set; } 
    public string PhNo { get; set; } 

    public int EmpNo { get; set; } 
    public string Title { get; set; } 
} 

//you can test as below 
     var pMap = Mapper.CreateMap<Person,PersonCompany>(); 
     pMap.ForAllMembers(d => d.Ignore()); 
     pMap.ForMember(d => d.Name, opt => opt.MapFrom(s => s.Name)) 
      .ForMember(d => d.PhNo, opt => opt.MapFrom(s => s.PhNo)); 

     var cMap = Mapper.CreateMap<Company, PersonCompany>(); 
     cMap.ForAllMembers(d => d.Ignore()); 
     cMap.ForMember(d => d.EmpNo, opt => opt.MapFrom(s => s.EmpNo)) 
      .ForMember(d => d.Title, opt => opt.MapFrom(s => s.Title)); 


     var person = new Person { Name = "PersonName", PhNo = "212-000-0000" }; 
     var personCompany = Mapper.Map<Person,PersonCompany>(person); 
     var company = new Company { Title = "Associate Director", EmpNo = 10001 }; 
     personCompany = Mapper.Map(company, personCompany); 

     Console.WriteLine("personCompany.Name={0}", personCompany.Name); 
     Console.WriteLine("personCompany.PhNo={0}", personCompany.PhNo); 
     Console.WriteLine("personCompany.EmpNo={0}", personCompany.EmpNo); 
     Console.WriteLine("personCompany.Title={0}", personCompany.Title); 
5
mapper.MergeInto<PersonCar>(person, car) 

con la risposta accettata come estensione-metodi, semplici e la versione generale:

public static TResult MergeInto<TResult>(this IMapper mapper, object item1, object item2) 
{ 
    return mapper.Map(item2, mapper.Map<TResult>(item1)); 
} 

public static TResult MergeInto<TResult>(this IMapper mapper, params object[] objects) 
{ 
    var res = mapper.Map<TResult>(objects.First()); 
    return objects.Skip(1).Aggregate(res, (r, obj) => mapper.Map(obj, r)); 
} 

dopo aver configurato la mappatura per ciascun tipo di input:

IMapper mapper = new MapperConfiguration(cfg => 
{ 
    cfg.CreateMap<Person, PersonCar>(); 
    cfg.CreateMap<Car, PersonCar>(); 
}).CreateMapper(); 
+0

la riusabilità è la chiave! –

+0

Avevo bisogno di qualcosa di simile oggi e la semplicità è così elegante, grazie! – PmanAce

Problemi correlati