2012-12-12 59 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