【问题标题】:Auto mapper to map conditional entity which doesn't work without using After map自动映射器映射不使用 After map 时无法工作的条件实体
【发布时间】:2017-07-05 06:23:54
【问题描述】:

您好,我正在使用 Auto mapper 来映射条件实体,如果不使用 After map 将无法工作,但与我不会使用的 After Map 一起工作时效果很好。 我想从 Domain.PermanentPlacement 但有条件地映射 InvoiceLineCreditHeader。

以下是映射代码。

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

这会报错

表达式树 lambda 可能不包含空传播运算符。

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

自动映射器中是否有任何方法可以在不使用 AfterMap 的情况下实现这一点?也有条件,但它也使用 linq 表达式。

有什么想法吗?

【问题讨论】:

    标签: c# linq lambda automapper


    【解决方案1】:

    您需要在中找到?. 运算符的替代方法

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

    Select-ing PermanentPlacementFirstOrDefault 之前很简单:

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

    【讨论】:

      【解决方案2】:

      您可以使用所需的逻辑创建一个单独的方法:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-13
        • 1970-01-01
        • 1970-01-01
        • 2010-09-24
        • 1970-01-01
        相关资源
        最近更新 更多