AutoMapper Map Детское свойство, которое также имеет определенную карту
У меня есть следующий объект домена:
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 имеет значение null.
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 для этого?
Ответы
Ответ 1
Вам просто нужно указать, что в отображении:
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)));
Ответ 2
Просто нарисуйте ребенка, используя self. Протестировано с помощью AutoMapper 6.1.1.
CreateMap<DomainClass, Child>();
CreateMap<DomainClass, Parent>()
.ForMember(d => d.Child, opt => opt.MapFrom(s => s));
Ответ 3
В Automapper 5.0 и выше, и если вы используете Profile для создания mapper:
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));
}
}
Ответ 4
Я столкнулся с этим вопросом раньше
то, как я решил, это двунаправленное отображение
как это
mapper.CreateMap<ChildInputDto, Child>();
mapper.CreateMap<Child, ChildInputDto>();
Я не знаю, почему, но это сработало со мной.