2012-01-20 1 views
36

У меня есть следующий домен объекта:AutoMapper Карта Ребенок недвижимости, который также имеет карту, определенную

public class DomainClass 
{ 
    public int Id { get; set; } 

    public string A { get; set; } 
    public string B { get; set; } 
} 

У меня есть следующие два объекта, которые я хочу сопоставить:

public class Parent 
{ 
    public int Id { get; set; } 
    public string A { get; set; } 

    public Child Child { get; set; } 
} 

public class Child 
{ 
    public int Id { get; set; } 
    public string B { get; set; } 
} 

Я настроил следующие карты:

Mapper.CreateMap<DomainClass, Parent>(); 
Mapper.CreateMap<DomainClass, Child>(); 

Если я составляю карту мой объект, используя следующий вызов, то свойство parent.Child равно нулю.

var domain = GetDomainObject(); 
var parent = Mapper.Map<DomainClass, Parent>(domain); // parent.Child is null 

Я знаю, что могу написать следующее:

var domain = GetDomainObject(); 
var parent = Mapper.Map<DomainClass, Parent>(domain); 
parent.Child = Mapper.Map<DomainClass, Child>(domain); 

Есть ли способ я могу исключить, что второй вызов и AutoMapper сделать это для меня?

ответ

64

Вам просто нужно указать, что в отображении:

Mapper.CreateMap<DomainClass, Child>(); 
Mapper.CreateMap<DomainClass, Parent>() 
     .ForMember(d => d.Id, opt => opt.MapFrom(s => s.Id)) 
     .ForMember(d => d.A, opt => opt.MapFrom(s => s.A)) 
     .ForMember(d => d.Child, 
       opt => opt.MapFrom(s => Mapper.Map<DomainClass, Child>(s))); 
+8

Не думал о вызове Mapper.Map внутри MapFrom. Спасибо – Dismissile

+16

Просто голова к другим людям, которые могут это увидеть сейчас. Это больше не работает, если вы используете контейнер IOC для создания экземпляра вашего класса IMapper. – PJH

+0

Вызов Mapper.Map внутри вашей конфигурации также разбивает ProjectTo на ошибку LINQ to Entities. –

4

В Automapper 5.0 и выше, и если вы используете профиль, чтобы создать картографа:

public class OrderMapper : Profile 
{ 
    public OrderMapper() 
    { 
     CreateMap<Order, OrderDto>(MemberList.None) 
      .ForMember(dest => dest.OrderId, 
       opts => opts.MapFrom(src => src.OrderId)) 
      .ForMember(dest => dest.OrderDate, 
       opts => opts.MapFrom(src => src.OrderDate)) 
      .ForMember(dest => dest.OrderedBy, 
       opts => opts.MapFrom(src => src.OrderedBy)) 
      .ForMember(dest => dest.ItemsDto, 
       opt => opt.MapFrom(src => src.Items)); 
    } 
} 

где назначение ItemsDto является:

public List<OrderItemDto> ItemsDto { get; set; } 

и источник:

public List<OrderItem> Items { get; set; } 

Затем создайте профиль сопоставителя для дочернего элемента/свойства:

public class OrderItemMapper : Profile 
{ 
    public OrderItemMapper() 
    { 
     CreateMap<OrderItem, OrderItemDto>(MemberList.None) 
      .ForMember(dest => dest.ItemId, 
       opts => opts.MapFrom(src => src.ItemId)) 
      .ForMember(dest => dest.ItemPrice, 
       opts => opts.MapFrom(src => src.ItemPrice)) 
      .ForMember(dest => dest.Name, 
       opts => opts.MapFrom(src => src.Name)) 
      .ForMember(dest => dest.Quantity, 
       opts => opts.MapFrom(src => src.Quantity)) 
      .ForMember(dest => dest.ItemTotal, 
       opts => opts.MapFrom(src => src.ItemTotal)); 
    } 

} 
-3

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

как это

mapper.CreateMap<ChildInputDto, Child>(); 
mapper.CreateMap<Child, ChildInputDto>(); 

Я не знаю, почему, но это сработало со мной

+0

Это похоже на несовместимое совпадение. Трудно понять, почему это поможет с сложностями сопоставления в одном из конкретных направлений. И если вы не знаете, почему это работает, это не очень полезно для других. – ADyson

9

Просто нарисуйте ребенка, используя себя. Протестировано с помощью AutoMapper 6.1.1.

 CreateMap<DomainClass, Child>(); 
     CreateMap<DomainClass, Parent>() 
      .ForMember(d => d.Child, opt => opt.MapFrom(s => s));