c# queryable Наследование AutoMapper и Linq




projectto automapper c# (3)

Я изучал, как использовать Inheritance в AutoMapper но я изо всех сил 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 и до тех пор, пока существует сопоставление между этими двумя объектами, оно будет работать, но оно не выглядит очень чистым.

Есть ли способ избежать этого?


Предполагая, что все необходимые свойства находятся в Article, вы можете создать для этого Custom 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>());

Предположим, у вас есть следующие классы:

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

Более того, вы можете создать собственный конвертер типов, чтобы избежать записи этих двух строк каждый раз, когда вам нужно отобразить Article в ArticleNewsItemDetailsViewModel .


Извиняюсь, если я слишком упрощаю это, но не могу просто добавить упомянутое вами прямое отображение:

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

Тем не менее, я все же рекомендую повторно реализовать ваше решение, чтобы вы отображали «как для». Вот хороший пример: http://automapper.codeplex.com/wikipage?title=Nested%20Mappings







automapper