当源对象没有继承关系时,如何使用 AutoMapper 包含子对象映射?

How can I include a child object mapping using AutoMapper when the source objects have no inheritance relationship?

我有一个类似这样的对象模型:

public class Concert {
    public Band Band { get; set; }
    public ConcertVenue Venue { get; set; }
}

public class TicketOrder { 
    public Concert Concert { get; set; }
    public string CustomerName { get; set; }
}

// DTOs for email and web views:
public class ConcertDto {
  public string Artist { get; set; }
  public string Venue { get; set; }
}

public class TicketOrderDto : ConcertDto {
   public string CustomerName { get; set; }
}

我正在使用 AutoMapper 将域对象映射到 DTO。这里的DTO有领域模型中不存在的继承关系(因为我发订票邮件的时候,想包含演唱会的所有信息)

我有一个这样定义的映射:

config.CreateMap<Concert, ConcertDto>()
  .ForMember(dto => dto.Artist, opt => opt.MapFrom(concert => concert.Band.Name))
  .ForMember(dto => dto.Venue, opt => opt.MapFrom(concert => concert.GetVenueSummary());

config.CreateMap<TicketOrder, ConcertDto>()
  .ForMember(dto => dto.Artist, opt => opt.MapFrom(concert => concert.Band.Name))
  .ForMember(dto => dto.Venue, opt => opt.MapFrom(concert => concert.GetVenueSummary())
  .ForMember(dto => dto.CustomerName, optn.MapFrom(order => order.Customer.FullName))
;

这些映射中有一些重复,我想要做的是在映射TicketOrderDto时重用Concert > ConcertViewData映射:

cfg.CreateMap<TicketOrder, TicketOrderDto>()
  // This is what I *want* but isn't valid AutoMapper syntax:
  .IncludeMembers(dto => dto, order => order.Concert)
  .ForMember(dto => dto.CustomerName, optn.MapFrom(order => order.Customer.FullName));

但这失败了:

System.ArgumentOutOfRangeException: Only member accesses are allowed. 
   dto => dto (Parameter 'memberExpressions')
   at AutoMapper.ExpressionExtensions.EnsureMemberPath(LambdaExpression exp, String name)

调用 .IncludeBase<> 无效,因为 ConcertOrder 不是从 Concert 派生的。

有没有一种简单的方法可以将一个映射导入另一个映射,但指定它应该从源类型的子对象映射?即“嘿,请将 source.Child 映射到此,然后 运行 常规源>此映射?”

我要在这里做一个假设,但我认为映射应该是从 TicketOrderTicketOrderDto,而不是 ConcertDto(不包含 CustomerName 属性) 因为给定的模型与给定的映射配置不匹配。

在这种情况下,您应该能够在票据映射器配置中使用 .AfterMap() 来从 Concert 映射到 ConcertDto

cfg.CreateMap<TicketOrder, TicketOrderDto>()            
    .ForMember(d => d.CustomerName, o => o.MapFrom(s => s.Order.Customer.Name))
    .AfterMap((s, d, context) => context.Mapper.Map(s.Concert, d));