19

我一直在研究如何在中使用继承,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,只要这两个对象之间存在映射,它就可以工作,但感觉不是很干净。

有什么办法可以避免这样做吗?

4

3 回答 3

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

此外,您可以创建自定义类型转换器以避免每次需要映射ArticleArticleNewsItemDetailsViewModel.

于 2012-12-21T00:54:37.673 回答
0

抱歉,如果我在脑海中过度简化了这一点,但您不能简单地添加您提到的直接映射:

CreateMap<ArticleNewsItem, ArticleNewsItemDetailsViewModel>();

对我来说,这是最简单,最干净的解决方案......

编辑 对不起,我误解了。如果不通过 .ConstructUsing() 或 .ConvertUsing() 方法(或以不整洁的方式进行操作)创建自定义映射,则无法将对象映射到嵌套属性...

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

..然后创建您的方法来构建 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;
    }

但是,我仍然建议重新实施您的解决方案,以便您映射'like for like'。这是一个很好的例子:http ://automapper.codeplex.com/wikipage?title=Nested%20Mappings

于 2012-12-14T15:39:52.850 回答
0

假设所有必需的属性都在文章中,您可以创建一个自定义值解析器来执行此操作,例如

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>());
于 2012-12-21T01:16:08.023 回答