2012-12-12 2 views
19

Ho cercato su come utilizzare l'ereditarietà in AutoMapper ma sto faticando a farlo funzionare completamente con Linq. Qui è il mio codice:AutoMapper ereditarietà e Linq

ho definito il mio mappature qui:

CreateMap<Article, ArticleDetailsViewModel>() 
    .Include<Article, ArticleNewsItemDetailsViewModel(); 

CreateMap<Article, ArticleNewsItemDetailsViewModel>(); 

ArticleDetailsViewModel è una classe base di ArticleNewsItemDetailsViewModel.

Ora qui sta il problema, se ho avuto:

CreateMap<ArticleNewsItem, ArticleNewsItemDetailsViewModel>(); 

Tutte le proprietà del modello di vista sarebbe mappare automaticamente, perché sono lo stesso nome per oggetto controparte LINQ. Tuttavia, perché sto usando la mappatura Article => ArticleNewsItemDetailsViewModel questo non è possibile, invece avrei dovuto definire ogni uno come:

.ForMember(x => x.Property1, opt => opt.MapFrom(src => src.ArticleNewsItem.Property1) 

ho pensato di spostare tutte le proprietà da ArticleNewsItemDetailsViewModel in un nuovo modello di vista e avere quella classe una proprietà all'interno di ArticleNewsItemDetailsViewModel e finché esiste una mappatura tra questi due oggetti, funzionerà, ma non si sentirà molto pulita.

C'è un modo per evitare di dover fare questo?

risposta

0

Mi scuso se ho più semplificare la presente nella mia testa, ma non posso semplicemente aggiungere la mappatura diretta si parla:

CreateMap<ArticleNewsItem, ArticleNewsItemDetailsViewModel>(); 

Per me questa è la soluzione più semplice e più pulita ...

EDIT Scusa, ho frainteso. Non è possibile associare un oggetto a una proprietà nidificato senza creare una mappa personalizzata tramite .ConstructUsing() o .ConvertUsing() metodi (o farlo nel modo disordinato) ...

Mapper.CreateMap<Article, ArticleNewsItemDetailsViewModel>().ConstructUsing(ConstructItem) 

..quindi creare il metodo per costruire l'ArticleNewsItemDetailsViewModel ...

private static ArticleNewsItemDetailsViewModel ConstructItem(Article source) 
    { 
     var newsItem = new ArticleNewsItem 
          { 
           Prop1 = source.Prop1, 
           Prop2 = source.Prop2 
          }; 

     var result = new ArticleNewsItemDetailsViewModel() 
         { 
          ArticleNewsItem = newsItem 
         }; 

     return result; 
    } 

Tuttavia io consiglierei comunque ri implementare la soluzione in modo che si sta mappando 'like for like'. Ecco un buon esempio: http://automapper.codeplex.com/wikipage?title=Nested%20Mappings

+0

Non penso che funzioni perché è un mapping di proprietà a una proprietà all'interno di un oggetto nidificato.Non una proprietà che è un oggetto che associa a un oggetto nidificato – ediblecode

+0

Mi spiace, ho frainteso. Non è possibile mappare un oggetto a una proprietà nidificata senza creare una mappa personalizzata tramite i metodi '.ConstructUsing()' o '.ConvertUsing()'. Dovresti davvero mappare come per piacere. Ecco un buon esempio: http://automapper.codeplex.com/wikipage?title=Nested%20Mappings – NinjaNye

+0

Grazie per aver compreso la domanda. Tuttavia, non è necessario definire il mapping all'interno di ConstructItem in quanto ciò può essere fatto utilizzando .ForMember e l'accesso alle proprietà nidificate. – ediblecode

1

Supponendo di avere le seguenti classi:

public class Article 
    { 
     public string Prop1 { get; set; } 
     public string Prop2 { get; set; } 
     public ArticleNewsItem ArticleNewsItem { get; set; } 
    } 

    public class ArticleDetailsViewModel 
    { 
     public string Prop1 { get; set; } 
    } 

    public class ArticleNewsItemDetailsViewModel : ArticleDetailsViewModel 
    { 
     public string Prop2 { get; set; } 
     public string Prop3 { get; set; } 
    } 

    public class ArticleNewsItem 
    { 
     public string Prop3 { get; set; } 
    } 

La mappatura dovrebbe essere simile di seguito:

var res = Mapper.Map<Article, ArticleNewsItemDetailsViewModel>(_article); 
Mapper.Map(_article.ArticleNewsItem, res); 

Inoltre è possibile creare custom type converter di evitare di scrivere queste due righe ogni volta che devi mappare Article a ArticleNewsItemDetailsViewModel.

0

Supponendo che tutte le proprietà richieste siano nell'articolo, è possibile creare un codice Custom Value Resolver, ad es.

public class ArticleNewsItemResolver : ValueResolver<Article, ArticleNewsItem> 
{ 
    protected override ArticleNewsItem ResolveCore(Article source) 
    { 
     return Mapper.DynamicMap<Article, ArticleNewsItem>(source); 
    } 
} 
... 

CreateMap<Article, ArticleNewsItemDetailsViewModel>() 
    .ForMember(src => src.NewsItem, opt => opt.ResolveUsing<ArticleNewsItemResolver>()); 
+0

L'attenzione degli elettori va spiegata? – James