2017-02-16 2 views
0

Hi Ich benutze Auto-Mapper, um bedingte Entität abzubilden, die nicht funktioniert, ohne Nach Map zu verwenden, aber gut mit After Map, die ich nicht gewonnen ' t zu verwenden. Ich möchte InvoiceLineCreditHeader von Domain.PermanentPlacement aber bedingt zuordnen.Auto-Mapper zum Zuordnen von bedingten Entitäten, die nicht funktionieren, ohne After-Map

Folgendes ist Mapping-Code.

MauritiusMapper.CreateMap<Domain.PermanentPlacement, InvoiceLineCreditHeader>() 
           .ForMember(desc => desc.ApplicantName, o => o.MapFrom(source => source.Candidate.FullName)) 
           .ForMember(desc => desc.DatePlaced, o => o.MapFrom(source => source.PlacementDate)) 
           .ForMember(desc => desc.ApproveDate, o => o.MapFrom(source => source.LastAuditItem.DateOfAction)) 
           .ForMember(desc => desc.CheckedBy, o => o.MapFrom(source => source.StartCheckedBy)) 
           .ForMember(desc => desc.Job, o => o.MapFrom(source => source.JobTitle)); 

     MauritiusMapper.CreateMap<InvoiceLineCreditSearchResult, InvoiceLineCreditData>() 
      .ForMember(d => d.InvoiceLineCredits, o => o.MapFrom(s => s.Credits)) 
      .ForMember(d => d.InvoiceLineCreditHeader, o => o.MapFrom(s => s.InvoiceLine)) 
      .ForMember(d => d.CreditReasons, o => o.MapFrom(s => s.CreditReasons)) 
      .ForMember(d => d.CreditStatuses, o => o.MapFrom(s => s.CreditStatuses)) 
      .ForMember(d => d.InvoiceLineCreditHeader, o => o.MapFrom(s => s.InvoiceLine.TransactionLines.OfType<PermanentPlacementTransactionLine>().FirstOrDefault()?.PermanentPlacement ?? s.ReissuePermanentPlacement)) 

Diese geben Fehler

Ein Ausdruck Baum Lambda kann kein Null ausbreitende Operator enthalten.

Welche erklärt sich durch Why can't I use the null propagation operator in lambda expressions?

wenn ich Aftermap verwenden, es funktioniert gut.

 MauritiusMapper.CreateMap<InvoiceLineCreditSearchResult, InvoiceLineCreditData>() 
      .ForMember(d => d.InvoiceLineCredits, o => o.MapFrom(s => s.Credits)) 
      .ForMember(d => d.InvoiceLineCreditHeader, o => o.MapFrom(s => s.InvoiceLine)) 
      .ForMember(d => d.CreditReasons, o => o.MapFrom(s => s.CreditReasons)) 
      .ForMember(d => d.CreditStatuses, o => o.MapFrom(s => s.CreditStatuses)) 
      //.ForMember(d => d.InvoiceLineCreditHeader, o => o.MapFrom(s => s.InvoiceLine.TransactionLines.OfType<PermanentPlacementTransactionLine>().FirstOrDefault()?.PermanentPlacement ?? s.ReissuePermanentPlacement)) 
      .AfterMap((s, d) => 
      { 
       var placement 
       = s.InvoiceLine.TransactionLines.OfType<PermanentPlacementTransactionLine>().FirstOrDefault()?.PermanentPlacement ?? s.ReissuePermanentPlacement; 
       // if (placement == null) return; 


       d.InvoiceLineCreditHeader.ApplicantId = placement.ApplicantId; 
       d.InvoiceLineCreditHeader.ApplicantName = placement.Candidate.FullName; 
       d.InvoiceLineCreditHeader.Job = placement.JobTitle; 
       d.InvoiceLineCreditHeader.DatePlaced = placement.PlacementDate; 
       d.InvoiceLineCreditHeader.PlacedBy = placement.PlacedBy; 
       d.InvoiceLineCreditHeader.ApprovedBy = placement.ApprovedBy; 
       d.InvoiceLineCreditHeader.ApproveDate = placement.LastAuditItem.DateOfAction; 
       d.InvoiceLineCreditHeader.CheckedBy = placement.StartCheckedBy; 
       d.InvoiceLineCreditHeader.StartDate = placement.StartDate; 
      }); 

Gibt es eine Möglichkeit in Auto Mapper ich kann dies ohne AfterMap verwenden? Es gibt auch eine Bedingung, aber es verwendet auch linq Ausdruck.

Irgendwelche Ideen?

Antwort

1

Sie benötigen Alternative zu ?. Betreiber zu finden in

s.InvoiceLine.TransactionLines.OfType<PermanentPlacementTransactionLine>() 
    .FirstOrDefault()?.PermanentPlacement 

, die von Select ganz einfach -ing PermanentPlacement vor FirstOrDefault:

s.InvoiceLine.TransactionLines.OfType<PermanentPlacementTransactionLine>() 
    .Select(e => e.PermanentPlacement).FirstOrDefault() 
1

Sie könnten ein separates Verfahren mit der gewünschten Logik erstellen:

private InvoiceLineCreditHeader GetInvoiceLineCreditHeader(InvoiceLineCreditSearchResult result) 
{ 
    // todo: get InvoiceLineCreditHeader conditionally 
    InvoiceLineCreditHeader header = new InvoiceLineCreditHeader(); 
    return header; 
} 

und nennen Sie es so:

.ForMember(d => d.InvoiceLineCreditHeader, o => o.MapFrom(s => GetInvoiceLineCreditHeader(s))) 
Verwandte Themen