Я ищу некоторые рекомендации по использованию ReverseMap при настройке сопоставлений для Automapper.
Я использую Automapper для сопоставления между объектами БД и моими моделями. Для ясности, вот упрощенный пример того, как они выглядят:
public class Document
{
public string Id { get; set; }
public List<Element> Elements { get; set; }
}
public class Element
{
public string Name { get; set; }
public virtual ElementType Type { get; set; }
}
public class ElementText : Element
{
public string Value { get; set; }
public Hashtable Attributes { get; set; }
public override ElementType Type { get; set; }
}
public class DocumentModel
{
public string Id { get; set; }
public List<ElementModel> Elements { get; set; }
}
public class ElementModel
{
public string Name { get; set; }
public virtual ElementType Type { get; }
}
public class ElementTextModel : ElementModel
{
public string Value { get; set; }
public Hashtable Attributes { get; set; }
public override ElementType Type { get { return ElementType.TEXT; } }
}
Таким образом, классы Document являются первичными классами и хранят списки элементов и производные классы от Element, такие как ElementText, в списке элементов.
Профиль сопоставления:
public MappingProfile()
{
this.CreateMap<Document, DocumentModel>().ReverseMap();
this.CreateMap<Element, ElementModel>().ReverseMap();
this.CreateMap<ElementText, ElementTextModel>().ReverseMap();
}
Теперь этот профиль работает в большинстве случаев, но не может отобразить производные классы в списке. Вместо этого он сопоставляет их с базовым классом. (Таким образом, элементы ElementText становятся Element, et c)
Я могу это исправить, используя IncludeAllDerived в профиле, например так:
public MappingProfile()
{
this.CreateMap<Document, DocumentModel>().ReverseMap();
this.CreateMap<Element, ElementModel>()
.IncludeAllDerived()
.ReverseMap();
this.CreateMap<ElementText, ElementTextModel>().ReverseMap();
}
Но, похоже, порядок .IncludeAllDerived ( ) и .ReverseMap () имеют значение. И единственный способ заставить производные классы работать в обоих направлениях - это использовать:
public MappingProfile()
{
this.CreateMap<Document, DocumentModel>().ReverseMap();
this.CreateMap<Element, ElementModel>()
.IncludeAllDerived()
.ReverseMap().IncludeAllDerived();
this.CreateMap<ElementText, ElementTextModel>().ReverseMap();
}
, который начинает немного неуклюже на мой вкус. Я предпочел бы отказаться от ReverseMap и явно определить отображение для обоих направлений.
public MappingProfile()
{
this.CreateMap<Document, DocumentModel>().ReverseMap();
this.CreateMap<Element, ElementModel>()
.IncludeAllDerived()
this.CreateMap<ElementModel, Element>()
.IncludeAllDerived();
this.CreateMap<ElementText, ElementTextModel>().ReverseMap();
}
Итак, мой вопрос, когда мне следует использовать ReverseMap? Никогда? Только в очень простых случаях?
Дает ли явное указание отображения в обоих направлениях один и тот же результат? Документация немного неясна, за исключением поста с инструкциями по использованию здесь Джимми говорит:
X AVOID ReverseMap в случаях, кроме случаев, когда сопоставляются только не сплющенные свойства верхнего уровня
Обратное сопоставление может очень быстро усложниться, и, если оно не очень простое, в конфигурации сопоставления могут отображаться бизнес-логи c.