我有一个复杂的对象,如:
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; }
}
我已为AutoMapper
配置了TradingDesk
:
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);
}
但是当我尝试将BusinessUnit
映射到Row
时,我不得不为AutoMapper
重新配置TradingDesk
:
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
应该使用已配置的来源&amp;映射TradingDesk
时需要将Row
映射到BusinessUnit
的目标类型映射。这样,我可以构建从最小到最大类型的配置,同时展平复杂对象,而无需为展平类型中的每个单独成员定义映射。
答案 0 :(得分:1)
实际语法可能有所不同,因为我以静态方式使用AutoMapper,但原则保持不变:
Mapper.CreateMap<BusinessUnit, Row>()
.ConvertUsing(source => Mapper.Map<TradingDesk, Row>(source.TradingDesk));
答案 1 :(得分:0)
首先,我认为您的交易台地图只是
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类。
答案 2 :(得分:0)
如果您不想创建特殊转换器或属性解析器,则可以在主对象的映射之后执行第二次映射,例如:
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);
在这种情况下,已映射对象而不创建新实例。