2012-12-12 96 views
19

我一直在尋找如何在AutoMapper中使用繼承,但我努力使其與Linq充分合作。這裏是我的代碼:AutoMapper繼承和Linq

我在這裏所定義的映射我:

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

CreateMap<Article, ArticleNewsItemDetailsViewModel>(); 

ArticleDetailsViewModel是一個基類的ArticleNewsItemDetailsViewModel

現在,這裏卻存在着問題,如果我有:

CreateMap<ArticleNewsItem, ArticleNewsItemDetailsViewModel>(); 
所有視圖模型屬性

會自動映射,因爲它們是相同的名稱作爲自己的LINQ對象對應。 然而,因爲我現在用的是Article => ArticleNewsItemDetailsViewModel映射這是不可能的,相反,我必須定義每一個爲:

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

我想過從ArticleNewsItemDetailsViewModel移動所有屬性到一個新的視圖模式,具有類ArticleNewsItemDetailsViewModel內的一個屬性,只要這兩個對象之間存在映射關係,它就可以工作,但它不會很乾淨。

有什麼辦法可以避免這樣做嗎?

回答

0

道歉,如果我在我的頭上簡化這一點,但不能只需添加你所提到的直接映射:

CreateMap<ArticleNewsItem, ArticleNewsItemDetailsViewModel>(); 

對我來說這是最簡單和乾淨的解決方案......

編輯 對不起,我誤解了。而無需創建通過.ConstructUsing()或.ConvertUsing)的自定義地圖(方法(或做不整潔的方式),你不能將對象映射到一個嵌套屬性...

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

..Then創建方法構建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; 
    } 

不過我還是會建議再實施你的解決方案,這樣你映射「像像」。這裏是一個很好的例子:http://automapper.codeplex.com/wikipage?title=Nested%20Mappings

+0

我不認爲這是可行的,因爲它的屬性映射到嵌套對象內的屬性。不是屬性映射到嵌套對象 – ediblecode

+0

對不起,我誤解了。如果不通過'.ConstructUsing()'或'.ConvertUsing()'方法創建自定義映射,則無法將對象映射到嵌套屬性。你應該真的像映射一樣。這是一個很好的例子:http://automapper.codeplex.com/wikipage?title=Nested%20Mappings – NinjaNye

+0

感謝您理解這個問題。但是,不需要在ConstructItem中定義映射,因爲可以使用.ForMember和訪問嵌套屬性完成該映射。 – ediblecode

1

假如你有以下類:

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

映射應該如下:

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

此外,您可以創建custom type converter避免編寫這兩條線每次您需要將Article映射到ArticleNewsItemDetailsViewModel

0

假設所有必需的屬性都在文章中,您可以創建一個Custom Value Resolver來執行此操作,例如

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

下來選民照顧解釋? – James