2017-02-16 12 views
0

Привет Я использую Auto mapper для привязки условного объекта, который не работает без использования карты After, но отлично работает с After Map, который я не выиграл ' t для использования. Я хочу отобразить InvoiceLineCreditHeader из Domain.PermanentPlacement, но условно.Auto mapper для привязки условного объекта, который не работает без использования После карты

Ниже приведен код сопоставления.

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

Это отдавание ошибки

Выражение дерево лямбда не может содержать нуль оператора распространяющегося.

Что объясняется Why can't I use the null propagation operator in lambda expressions?

, если я использую Aftermap, он отлично работает.

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

Есть ли способ в auto mapper Я могу достичь этого без использования AfterMap? есть условие, но оно также использует выражение linq.

Любые идеи?

ответ

1

Вы должны найти альтернативу ?. оператора в

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

, которая довольно проста по Select -ную PermanentPlacement перед тем FirstOrDefault:

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

Вы можете создать отдельный метод с нужной логикой:

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

и назовите его так:

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