2012-12-12 11 views
19

Ich habe darüber nachgedacht, wie Vererbung in AutoMapper verwenden, aber ich kämpfe, um es vollständig mit Linq arbeiten. Hier ist mein Code:AutoMapper Vererbung und Linq

ich meine Abbildungen hier definiert haben:

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

CreateMap<Article, ArticleNewsItemDetailsViewModel>(); 

ArticleDetailsViewModel ist eine Basisklasse von ArticleNewsItemDetailsViewModel.

Hier liegt das Problem, wenn ich habe:

CreateMap<ArticleNewsItem, ArticleNewsItemDetailsViewModel>(); 

alle Eigenschaften im View-Modell automatisch abbilden würde, weil sie die gleichen Namen wie ihr Linq Objekt Pendant sind. jedoch, weil ich die Article => ArticleNewsItemDetailsViewModel Mapping verwende dies nicht möglich ist, stattdessen würde ich jede definieren müssen ein als:

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

Ich dachte über alle Eigenschaften von ArticleNewsItemDetailsViewModel in eine neue Ansicht Modell bewegen und diese Klasse mit eine Eigenschaft innerhalb der ArticleNewsItemDetailsViewModel und solange es eine Zuordnung zwischen diesen beiden Objekten gibt, dann wird es funktionieren, aber es fühlt sich nicht sehr sauber an.

Gibt es eine Möglichkeit, dies zu vermeiden?

Antwort

0

Entschuldigt, wenn ich über die Vereinfachung in meinem Kopf bin, aber kann man nicht einfach die direkte Zuordnung hinzufügen, die Sie erwähnen:

CreateMap<ArticleNewsItem, ArticleNewsItemDetailsViewModel>(); 

Für mich die einfachste und sauberste Lösung ist ...

EDIT Entschuldigung, ich missverstanden. Sie können nicht ein Objekt in eine verschachtelten Eigenschaft zuordnen, ohne eine benutzerdefinierte Karte über .ConstructUsing Erstellen() oder .ConvertUsing() Methoden (oder die unordentliche Art und Weise zu tun) ...

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

..Then erstellen Sie Ihre Methode, um die ArticleNewsItemDetailsViewModel zu bauen ...

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

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

     return result; 
    } 

Allerdings würde ich noch re Umsetzung Ihrer Lösung empfehlen, so dass Sie ‚like for like‘ zuordnen. Hier ist ein gutes Beispiel: http://automapper.codeplex.com/wikipage?title=Nested%20Mappings

+0

Ich glaube nicht, dass dies funktioniert, weil es eine Eigenschaft ist, die auf eine Eigenschaft innerhalb eines verschachtelten Objekts zuordnet.Keine Eigenschaft, die ein Objekt auf ein verschachteltes Objekt abbildet – ediblecode

+0

Entschuldigung, ich habe es falsch verstanden. Sie können ein Objekt keiner geschachtelten Eigenschaft zuordnen, ohne eine benutzerdefinierte Zuordnung über die Methoden ".ConstructUsing()" oder ".ConvertUsing()" zu erstellen. Sie sollten wirklich für wie mappen. Hier ist ein gutes Beispiel: http://automapper.codeplex.com/wikipage?title=Nested%20Mappings – NinjaNye

+0

Vielen Dank für das Verständnis der Frage. Es ist jedoch nicht erforderlich, das Mapping in ConstructItem zu definieren, da dies mit .ForMember geschehen und auf geschachtelte Eigenschaften zugreifen kann. – ediblecode

1

Angenommen, Sie die folgenden Klassen:

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

Die Abbildung wie folgt aussehen sollte:

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

Außerdem können Sie custom type converter erstellen zu vermeiden, dass diese zwei Zeilen zu schreiben jedes Mal, wenn Sie Article zu ArticleNewsItemDetailsViewModel zuordnen müssen.

0

Unter der Annahme, dass alle erforderlichen Eigenschaften in Artikel sind, könnten Sie eine Custom Value Resolver erstellen, z.

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

Down Wähler zu erklären? – James