在AutoMapper中将复杂类型映射到平面类型

我有一个复杂的对象,如:

public class BusinessUnit
{
        public TradingDesk TradingDesk { get; }
        public string Division { get; }

        public BusinessUnit(string division, TradingDesk tradingDesk)
        {
            Division = division;
            TradingDesk = tradingDesk;
        }
}

我想将其映射到平面类型:

public class Row
{
   //TradingDesk properties
   public string TraderFirstName { get; set; }
   public string TraderLastName { get; set; }
   public string TradingDeskName { get; set; }

   public string Division { get; set; }
}

我已经为TradingDesk配置了AutoMapper

CreateMap<TradingDesk, Row>().ForMember(vm => vm.TradingDeskName, op => op.MapFrom(src => src.Name));

所以下面的测试通过:

[Test]
public void Should_Map_TradingDesk_To_Row()
{
    var tradingDesk = Fixture.Create<TradingDesk>();

    var mapped = AutoMapper.Map<Row>(tradingDesk);

    mapped.TradingDeskName.Should()
            .Be(tradingDesk.Name);
    mapped.TraderFirstName.Should()
            .Be(tradingDesk.Trader.FirstName);
    mapped.TraderLastName.Should()
            .Be(tradingDesk.Trader.LastName);
}

但是,当我尝试映射BusinessUnitRow ,我不得不重新AutoMapperTradingDesk这样:

CreateMap<BusinessUnit, Row>()
   .ForMember(vm => vm.TradingDeskName, op => op.MapFrom(src => src.TradingDesk.Name))
   .ForMember(vm => vm.TraderFirstName, op => op.MapFrom(src => src.TradingDesk.Trader.FirstName))
   .ForMember(vm => vm.TraderLastName, op => op.MapFrom(src => src.TradingDesk.Trader.LastName));

我期望AutoMapper在映射BusinessUnit时需要将TradingDesk映射到Row时,应使用已配置的源和目标类型映射。 通过这种方式,我可以构建从最小型到最大型的配置,同时展平复杂的对象,而无需为扁平类型中的每个单独成员定义映射。


实际的语法可能会有所不同,因为我以静态的方式使用AutoMapper,但原理保持不变:

Mapper.CreateMap<BusinessUnit, Row>()
      .ConvertUsing(source => Mapper.Map<TradingDesk, Row>(source.TradingDesk));

首先,我认为你的交易平台地图只是

CreateMap<TradingDesk, Row>();

如果内存为我提供了正确的服务,因为您的目标成员在“。”时匹配源成员名称。 被删除,那么你不需要明确指定它。

如果你改变你的Row类到这个

public class Row
{
   //TradingDesk properties
   public string TradingDeskTraderFirstName { get; set; }
   public string TradingDeskTraderLastName { get; set; }
   public string TradingDeskName { get; set; }

   public string Division { get; set; }
}

你的地图会是

CreateMap<BusinessUnit, Row>(); 

如果你永远不会映射到TradingDesk,那么删除该地图。

如果这是在一些配置文件中定义的,你也可以说

RecognizePrefixes("TradingDesk"); 

然后你不需要改变你的Row类。


如果您不想创建特殊的转换器或属性解析器,则可以在主对象的映射之后执行第二个映射,例如:

Mapper.Initialize(cfg =>
{
    cfg.CreateMap<TradingDesk, Row>()
        .ForMember(vm => vm.TradingDeskName, op => op.MapFrom(src => src.Name));
    cfg.CreateMap<BusinessUnit, Row>()
        .AfterMap((businessUnit, row) => { Mapper.Map(businessUnit.TradingDesk, row); });
});

var source = new BusinessUnit("division", new TradingDesk { TraderFirstName = "FirstName", TraderLastName = "LastName", Name = "DeskName" });

var dest = Mapper.Map<Row>(source);

在这种情况下,该对象已被映射而不创建新的实例。

链接地址: http://www.djcxy.com/p/6381.html

上一篇: Map complex type to flat type in AutoMapper

下一篇: automapper automapping deep object to flat object and back