AutoMapper Map Дочернее свойство, для которого также определена карта - PullRequest
47 голосов
/ 20 января 2012

У меня есть следующий объект домена:

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 сделал это для меня?

Ответы [ 4 ]

83 голосов
/ 20 января 2012

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

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)));
26 голосов
/ 18 июля 2017

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

        CreateMap<DomainClass, Child>();
        CreateMap<DomainClass, Parent>()
            .ForMember(d => d.Child, opt => opt.MapFrom(s => s));
6 голосов
/ 16 августа 2016

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

}
0 голосов
/ 06 декабря 2016

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

как это

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...