2016-04-04 25 views
8

devo classi comeAutoMapper.Mapper.CreateMap <TSource, tIndirizzo>()' è obsoleto

class A 
{ 
public int id {get; set;} 
} 

class B 
{ 
public C c {get; set;} 
} 

class C 
{ 
public int id {get; set;} 
public string Name {get; set;} 
} 

mia esigenza è quella mappa ID di classe A per id di classe C. Ora quello che ero fare fino ad ora era: Mapper.CreateMap(). ForMember (des => des.C.Id, src => src.MapFrom (x => x.id));

e funzionava bene.

Ora sembra che Auto Mapper abbia cambiato la loro implementazione. e ricevo l'avviso come segue:

AutoMapper.Mapper.CreateMap() 'è obsoleto:' La creazione dinamica delle mappe verrà rimossa nella versione 5.0. Utilizzare un'istanza di MapperConfiguration e archiviarla staticamente secondo necessità o Mapper.Initialize. Usa CreateMapper per creare un'istanza del mapper.

Ho bisogno di mappare alcune proprietà di classi che hanno nome e struttura differenti. Qualsiasi aiuto su questo.

+2

Dai un'occhiata a [questo] (http://stackoverflow.com/questions/35256008/automapper-migrating-fro m-static-api) post. –

+0

Il commento di diiN dovrebbe indirizzarti nella giusta direzione, tuttavia se sei ancora in difficoltà puoi installare una versione precedente usando NuGet o utilizzando il prompt dei comandi: Install-Package AutoMapper -Version 4.1.0 –

risposta

16

precedenza

Mapper.CreateMap<Src, Dest>() 
.ForMember(d => d.UserName, opt => opt.MapFrom(/* ????? */)); 

Il problema qui è definizioni di mappatura sono statici, definito una volta riutilizzati per tutta la durata dell'applicazione. Prima di 3.3, dovresti ridefinire la mappatura su ogni richiesta, con il valore hardcoded. E poiché la configurazione della mappatura viene creata in una posizione separata rispetto alla nostra esecuzione di mappatura, abbiamo bisogno di un modo per introdurre un parametro di runtime nella nostra configurazione, quindi fornirlo durante l'esecuzione.

Questo si ottiene in due parti: la definizione del mapping in cui creiamo un parametro runtime, quindi al momento dell'esecuzione quando lo forniamo. Per creare la definizione di mappatura con un parametro di runtime, noi “falso” una chiusura che include un nome variabile locale:

Mapper.Initialize(cfg => { 

string userName = null; 
cfg.CreateMap<Source, Dest>() 
    .ForMember(d => d.UserName, 
     opt => opt.MapFrom(src => userName) 
    ); 
}); 

Per ulteriori informazioni see this

Per una o più classi

cfg.CreateMissingTypeMaps = true; 
cfg.CreateMap<Source, Dest>() 
    .ForMember(d => d.UserName, 
     opt => opt.MapFrom(src => userName) 
    ); 

cfg.CreateMap<AbcEditViewModel, Abc>(); 
cfg.CreateMap<Abc, AbcEditViewModel>(); 
}); 

Nella classe di mappatura

IMapper mapper = config.CreateMapper(); 
    var source = new AbcEditViewModel(); 
    var dest = mapper.Map<AbcEditViewModel, Abct>(source); 
+0

funziona correttamente MA C'È UN PROBLEMA DOPO. Nel caso in cui abbiamo esattamente le stesse proprietà in due classi di solo Mapper.map (Source, Destination) funziona e non è necessario mappare esplicitamente. Ma una volta che abbiamo usato Mapper.Initialize (CFG => { String username = null; cfg.CreateMap () .ForMember (d => d.UserName, opt => opt.MapFrom (src => userName) ); }); Nessun altro Mapper.map (Origine, Destinazione) funziona (per quale origine e destinazione hanno le stesse proprietà e struttura) – Sharad

+0

La tua classe di origine e destinazione è generica? Devi creare una mappa per ogni combinazione di mappatura –

+0

no, non ho classi generiche. – Sharad

0

Infine ho trovato la risoluzione. Stavo facendo: Mapper.Initialize{ Mapping field from source to destination } in App_art e aggiungendo questo file a global.asax -> Application_Start() -> GlobalConfiguration.

ho bisogno di aggiungere una riga di più dentro la mia Mapper.Initialize quali è cfg.CreateMissingTypeMaps = true;

Ora questo codice lavorerà per mapping esplicito in cui due classi non hanno la stessa struttura e nomi delle proprietà.

Oltre a questo, se abbiamo bisogno di mappare le proprietà di due classi con la stessa struttura, funzionerà anche il codice Mapper.map(source, destination), che non funzionava prima.

Fammi sapere se qualcuno ha difficoltà con la soluzione. Grazie a tutti per la risposta di cui sopra.

0

Un altro modo che sembra un po 'più pulito è quello di fare una classe MappingProfile che eredita dalla classe di profilo di automapper

public class MappingProfile:Profile 
{ 
    public MappingProfile() 
    { 
     CreateMap<Source1, Destination1>(); 
     CreateMap<Source2, Destination2>(); 
     ... 
    } 
} 

Poi si inizializza la mappatura con Mapper.Initialize(c => c.AddProfile<MappingProfile>()); nel codice di avvio

che permetterà per utilizzare la mappatura ovunque chiamando

destination1Collection = source1Collection.Select(Mapper.Map<Source1, Destination1>);