【问题标题】:Automapper Aftermap alternative for Nested MappingAutomapper Aftermap 替代嵌套映射
【发布时间】:2021-06-04 02:28:59
【问题描述】:

我在 Asp.net Core Web API 项目中有以下模型。

public class TestExamReport
    {
        public string PatientKey { get; set; }

        public string OPDiagnosis { get; set; }

        public string ORDiagnosis { get; set; }

        public OPExam OPExamDetails { get; set; }

        public ORExam ORExamDetails { get; set; }

    }

     public class OPExam
    {
        public BaselineOP Baseline { get; set; }

        public CurrentOP Current { get; set; }
    }

    public class ORExam
    {
        public BaselineOR Baseline { get; set; }

        public CurrentOR Current { get; set; }
    }

    public class BaselineOP 
    {
        public string SeriesKey { get; set; }
        public DateTime SeriesDate { get; set; }
        public string ImagePath { get; set; }
        public DateTime? ReviewedOn { get; set; }
    }

    public class BaselineOR
    {
        public string SeriesKey { get; set; }
        public DateTime SeriesDate { get; set; }
        public string ImagePath { get; set; }
        public DateTime? ReviewedOn { get; set; }
    }

    public class CurrentOP : BaselineOP
    {
        public bool ThresholdFlag { get; set; }
    }
    
    public class CurrentOR : BaselineOR
    {
        public bool ThresholdFlag { get; set; }
    }

我在数据访问层中有以下模型:

 public class TestExamResult
    {
        public string Patientkey { get; set; }
        
        public string OPDiagnosis { get; set; }
        
        public string ORDiagnosis { get; set; }

        public string BaselineOPSeriesKey { get; set; }

        public DateTime BaselineOPSeriesDate { get; set; }

        public string BaselineOPImage { get; set; }

        public DateTime? BaselineOPReviewedOn { get; set; }

        public string CurrentOPSeriesKey { get; set; }

        public DateTime CurrentOPSeriesDate { get; set; }

        public string CurrentOPImage { get; set; }

        public DateTime? CurrentOPReviewedOn { get; set; }

        public bool CurrentOPThresholdFlag { get; set; }

        public string BaselineORSeriesKey { get; set; }

        public DateTime BaselineORSeriesDate { get; set; }

        public string BaselineORImage { get; set; }

        public DateTime? BaselineORReviewedOn { get; set; }

        public string CurrentORSeriesKey { get; set; }

        public DateTime CurrentORSeriesDate { get; set; }

        public string CurrentORImage { get; set; }

        public DateTime? CurrentORReviewedOn { get; set; }

        public bool CurrentORThresholdFlag { get; set; }

    }

我有以下 Automapper 配置文件类:

public class PersonProfile : Profile
{
    public PersonProfile()
    {
       
           CreateMap<TestExamResult, TestExamReport>()
            .ForMember(dest => dest.OPExamDetails, src => src.Ignore())
            .ForMember(dest => dest.ORExamDetails, src => src.Ignore())
            .AfterMap((Src, Dest) =>
            Dest.OPExamDetails = new OPExam
            {
                Baseline = new BaselineOP()
                {
                    SeriesKey = Src.BaselineOPSeriesKey,
                    SeriesDate = Src.BaselineOPSeriesDate,
                    ImagePath = Src.BaselineOPImage,
                    ReviewedOn = Src.BaselineOPReviewedOn
                },
                Current = new CurrentOP()
                {
                    SeriesKey = Src.CurrentOPSeriesKey,
                    SeriesDate = Src.CurrentOPSeriesDate,
                    ImagePath = Src.CurrentOPImage,
                    ReviewedOn = Src.CurrentOPReviewedOn,
                    ThresholdFlag = Src.CurrentOPThresholdFlag
                }
            })
             .AfterMap((Src, Dest) =>
             Dest.ORExamDetails = new ORExam
             {
                 Baseline = new BaselineOR()
                 {
                     SeriesKey = Src.BaselineORSeriesKey,
                     SeriesDate = Src.BaselineORSeriesDate,
                     ImagePath = Src.BaselineORImage,
                     ReviewedOn = Src.BaselineORReviewedOn
                 },
                 Current = new CurrentOR()
                 {
                     SeriesKey = Src.CurrentORSeriesKey,
                     SeriesDate = Src.CurrentORSeriesDate,
                     ImagePath = Src.CurrentORImage,
                     ReviewedOn = Src.CurrentORReviewedOn,
                     ThresholdFlag = Src.CurrentORThresholdFlag
                 }
             });
    }
}

上面的代码运行良好,因为我使用的是 AfterMap。但是,有没有比使用 AfterMap 更好的方法来编写它? AfterMap 感觉就像我在自己编写映射代码,而不是更好地使用 Automapper。

我还尝试了与 Automapper 文档不同的嵌套对象映射方法。但是,在我的情况下它不起作用,我遇到了一个或另一个错误。

编辑:

我也尝试过下面的映射,但 TestExamReport 对象为空,只有 PatientKey 有值。

CreateMap<TestExamResult, TestExamReport>();
                //Below two lines don't have impact, even 
                //If they are remove, objects are still null
                CreateMap<TestExamResult, OPExam>();
                CreateMap<TestExamResult, ORExam>();
                CreateMap<TestExamResult, BaselineOP>()
                    .ForMember(dest => dest.SeriesKey, src => src.MapFrom(y => y.BaselineOPSeriesKey))
                    .ForMember(dest => dest.SeriesDate, src => src.MapFrom(y => y.BaselineOPSeriesDate))
                    .ForMember(dest => dest.ImagePath, src => src.MapFrom(y => y.BaselineOPImage))
                    .ForMember(dest => dest.ReviewedOn, src => src.MapFrom(y => y.BaselineOPReviewedOn))
                    .ReverseMap();
                CreateMap<TestExamResult, CurrentOP>()
                    .ForMember(dest => dest.SeriesKey, src => src.MapFrom(y => y.CurrentOPSeriesKey))
                    .ForMember(dest => dest.SeriesDate, src => src.MapFrom(y => y.CurrentOPSeriesDate))
                    .ForMember(dest => dest.ImagePath, src => src.MapFrom(y => y.CurrentOPImage))
                    .ForMember(dest => dest.ReviewedOn, src => src.MapFrom(y => y.CurrentOPReviewedOn))
                    .ForMember(dest => dest.ThresholdFlag, src => src.MapFrom(y => y.CurrentOPThresholdFlag))
                    .ReverseMap();
                CreateMap<TestExamResult, BaselineOR>()
                   .ForMember(dest => dest.SeriesKey, src => src.MapFrom(y => y.BaselineORSeriesKey))
                   .ForMember(dest => dest.SeriesDate, src => src.MapFrom(y => y.BaselineORSeriesDate))
                   .ForMember(dest => dest.ImagePath, src => src.MapFrom(y => y.BaselineORImage))
                   .ForMember(dest => dest.ReviewedOn, src => src.MapFrom(y => y.BaselineORReviewedOn))
                   .ReverseMap();
                CreateMap<TestExamResult, CurrentOR>()
                    .ForMember(dest => dest.SeriesKey, src => src.MapFrom(y => y.CurrentORSeriesKey))
                    .ForMember(dest => dest.SeriesDate, src => src.MapFrom(y => y.CurrentORSeriesDate))
                    .ForMember(dest => dest.ImagePath, src => src.MapFrom(y => y.CurrentORImage))
                    .ForMember(dest => dest.ReviewedOn, src => src.MapFrom(y => y.CurrentORReviewedOn))
                    .ForMember(dest => dest.ThresholdFlag, src => src.MapFrom(y => y.CurrentORThresholdFlag))
                    .ReverseMap();

【问题讨论】:

  • thisthis
  • 这两个都试过了,还是不行。要么我收到错误消息,要么 TestExamReport 中的对象为空,但 PatientKey 除外。如果您看到这两个模型,我将数据访问层模型映射到 BaselineOP/BaselineOR 的三级深度的属性。
  • 只要您拥有所有嵌套的地图,嵌套的级别就无关紧要。从简单的开始,然后逐步向上。
  • @LucianBargaoanu 查看编辑。谢谢。

标签: asp.net-core-webapi asp.net-core-5.0 automapper-10


【解决方案1】:

我已经从thisthis 解决了这个问题。

下面是我让它工作的示例代码:

cfg.CreateMap<TestExamResult, BaselineOP>()
                .ForMember(d => d.SeriesKey, opt => opt.MapFrom(src => src.BaselineOPSeriesKey))
                .ForMember(d => d.SeriesDate, opt => opt.MapFrom(src => src.BaselineOPSeriesDate))
                .ForMember(d => d.ImagePath, opt => opt.MapFrom(src => src.BaselineOPImage))
                .ForMember(d => d.ReviewedOn, opt => opt.MapFrom(src => src.BaselineOPReviewedOn))
                .ReverseMap();
            cfg.CreateMap<TestExamResult, BaselineOR>()
                .ForMember(d => d.SeriesKey, opt => opt.MapFrom(src => src.BaselineORSeriesKey))
                .ForMember(d => d.SeriesDate, opt => opt.MapFrom(src => src.BaselineORSeriesDate))
                .ForMember(d => d.ImagePath, opt => opt.MapFrom(src => src.BaselineORImage))
                .ForMember(d => d.ReviewedOn, opt => opt.MapFrom(src => src.BaselineORReviewedOn))
                .ReverseMap();
            cfg.CreateMap<TestExamResult,OPExam>()
                .ForMember(d=>d.BaselineOP, opt => opt.MapFrom(src => src)).ReverseMap();
                cfg.CreateMap<TestExamResult,ORExam>()
                .ForMember(d=>d.BaselineOR, opt => opt.MapFrom(src => src)).ReverseMap();
            cfg.CreateMap<TestExamResult, TestExamReport>()
                .ForMember(d=>d.OPExam, opt => opt.MapFrom(src => src))
                .ForMember(d=>d.ORExam, opt => opt.MapFrom(src => src))
                .ReverseMap();

上面代码我现在面临的唯一问题是,如果所有属性值都为空,例如对于 BaselineOP,我想将其设置为空。为此,我需要更多地探索 Automapper。

编辑:

在查看this 帖子后,如果 BaselineOP 的所有属性都为空,我可以将其标记为空。它正在工作。

cfg.CreateMap<TestExamResult,OPExam>()
    .ForMember(d=>d.BaselineOP,  b => b.MapFrom((c, a, obj, context) => !string.IsNullOrEmpty(c.BaselineOPSeriesKey) ? context.Mapper.Map<BaselineOP>(c) : null))
    .ReverseMap();

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-07-17
  • 2017-07-20
  • 2020-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多