2012-12-12 13 views
19

Szukałem, jak korzystać z dziedziczenia w AutoMapper, ale staram się, aby działał w pełni z Linq. Tu jest mój kodu:Dziedziczenie AutoMapper i Linq

Mam zdefiniowane moje mapowania tutaj:

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

CreateMap<Article, ArticleNewsItemDetailsViewModel>(); 

ArticleDetailsViewModel to klasa bazowa ArticleNewsItemDetailsViewModel.

Teraz tutaj tkwi problem, gdybym miał:

CreateMap<ArticleNewsItem, ArticleNewsItemDetailsViewModel>(); 

wszystkich właściwości w modelu widoku automatycznie map ponieważ są one takie same jak ich nazwa obiektu Linq odpowiednika. Jednak, ponieważ używam mapowanie Article => ArticleNewsItemDetailsViewModel to nie jest możliwe, a nie będę musiał zdefiniować każdy jak:

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

myślałem o przeniesieniu wszystkich właściwości z ArticleNewsItemDetailsViewModel do nowego modelu widoku i posiadające tej klasy właściwość wewnątrz ArticleNewsItemDetailsViewModel i dopóki istnieje mapowanie między tymi dwoma obiektami, to zadziała, ale nie będzie bardzo czysta.

Czy istnieje sposób na uniknięcie tego obowiązku?

Odpowiedz

0

Przepraszam, jeśli jestem na uproszczenie to w głowie, ale nie można po prostu dodać bezpośrednie odwzorowanie można wymienić:

CreateMap<ArticleNewsItem, ArticleNewsItemDetailsViewModel>(); 

Dla mnie to jest najprostszym i najczystszych rozwiązanie ...

EDYTOWANIE Przepraszam, źle mnie zrozumiałem. Nie można odwzorować obiekt do nieruchomości bez tworzenia zagnieżdżonych mapę niestandardową poprzez .ConstructUsing() lub() .ConvertUsing metod (lub robi to nieporządny sposób) ...

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

..Then tworzyć swoje Sposób budować 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; 
    } 

jednak chciałbym jeszcze polecić ponowne wdrożenie swojego rozwiązania, dzięki czemu są mapowania „jak na niczym”. Oto dobry przykład: http://automapper.codeplex.com/wikipage?title=Nested%20Mappings

+0

Nie sądzę, że to działa, ponieważ jest to właściwość odwzorowująca właściwość w obiekcie zagnieżdżonym.Nie jest właściwością, która jest mapowaniem obiektów do zagnieżdżonego obiektu. – ediblecode

+0

Przepraszam, źle mnie zrozumiałem. Nie można odwzorować obiektu na zagnieżdżoną właściwość bez tworzenia niestandardowej mapy za pomocą metod '.ConstructUsing()' lub '.ConvertUsing()'. Powinieneś naprawdę mapować, jak na przykład. Oto dobry przykład: http://automapper.codeplex.com/wikipage?title=Nested%20Mappings – NinjaNye

+0

Dzięki za zrozumienie pytania. Jednak nie ma potrzeby definiowania odwzorowania w ConstructItem, ponieważ można to zrobić za pomocą .ForMember i uzyskiwanie dostępu do zagnieżdżonych właściwości. – ediblecode

1

Przypuśćmy masz następujących klas:

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

Mapowanie powinien wyglądać jak poniżej:

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

Ponadto można tworzyć custom type converter aby uniknąć pisania tych dwóch linii za każdym razem musisz mapować Article na ArticleNewsItemDetailsViewModel.

0

Zakładając, że wszystkie wymagane właściwości znajdują się w Artykule, można utworzyć w tym celu Custom Value Resolver, np.

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

Mniejsza opieka wyborców, aby wyjaśnić? – James