2016-06-30 5 views
12

Ich habe ein komplexes Objekt wie:Karten komplexer Typ zu flachen Typ in AutoMapper

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

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

ich dies den flachen Typen zuordnen möge:

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

ich bereits AutoMapper für TradingDesk konfiguriert haben:

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

so wird der folgende Test vorbei:

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

Aber wenn ich versuche zu kartieren BusinessUnit- Ich habe AutoMapper für TradingDesk als solche neu zu konfigurieren:

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

Ich erwarte, dass AutoMapper & Zieltyp-Mapping die bereits konfigurierten Quelle verwenden sollte, wenn es braucht um TradingDesk zu zu kartieren, während BusinessUnit kartiert wird. Auf diese Weise kann ich die Konfiguration vom kleinsten zum größten Typ erstellen, während ein komplexes Objekt abgeflacht wird, ohne dass die Zuordnung für jedes einzelne Element im abgeflachten Typ definiert werden muss.

Antwort

1

tatsächliche Syntax könnte unterscheiden, weil ich AutoMapper in einer statischen Art und Weise unter Verwendung von bin, aber das Prinzip bleibt das gleiche:

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

Aber ich habe keine 'IMapper'-Instanz, die aus der Konfiguration dort erstellt wird; Ihr Code explodiert also mit 'AutoMapperMappingException' – aateeque

+0

Wenn Sie [diesen Beitrag] (http://stackoverflow.com/a/9404417/1558010) betrachten, sind Ihre Optionen möglicherweise eingeschränkt, wenn Sie sich nicht auf den statischen Mapper verlassen –

0

Zunächst ich Ihre Karte für den Handel Schreibtisch denken würde

CreateMap<TradingDesk, Row>(); 
gerade sein

Wenn Speicher mir richtig dient, da Ihr Ziel Mitglied Quellenname entspricht, wenn "." entfernt werden, dann müssen Sie es nicht explizit angeben.

Wenn Sie Ihre Zeilenklasse dieser

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

Ihre Karte

ändern würde

CreateMap<BusinessUnit, Row>(); 

Wenn Sie werden niemals zur Karte TradingDesk, dann entfernen Sie diese Karte.

Wenn dies in einem Profil definiert ist, können Sie auch

sagen
RecognizePrefixes("TradingDesk"); 

und dann müssen Sie Ihre Zeilenklasse nicht ändern.

0

Wenn Sie nicht wollen, eine spezielle Konverter oder Eigenschaft Resolver erstellen können Sie die zweite Abbildung nach der Karte des Hauptobjekts durchführen, zum Beispiel:

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

In diesem Fall wird das Objekt zugeordnet wurde, ohne Erstellen einer neuen Instanz

Verwandte Themen