如何为两种不同场景配置AutoMapper单一映射规则?
问题:AutoMapper实现行程原因的条件映射
从API获取行程数据后,需通过AutoMapper将API模型TripModel映射至EF Core实体Trip并存储到SQL Server数据库。大部分映射逻辑简单直接,但存在以下特殊场景需要处理:
- 当
TripModel.ReasonForTravel(int?类型)有值且大于0时,需通过自定义TravelReasonConverter将其转换为目标字符串; - 当
TripModel.ReasonForTravel无值或小于等于0时,直接取用TripModel.CustomTravelReason的属性值。
如何在AutoMapper的CreateMap配置中实现该逻辑,完成一步映射?以下是现有代码:
public class TripModel { public string Firstname { get; set; } public string Lastname { get; set; } public int? ReasonForTravel { get; set; } public string CustomTravelReason { get; set; } // 其他无关属性 } public class Trip { public string Firstname { get; set; } public string Lastname { get; set; } public string ReasonForTrip { get; set; } } public class TripProfile : Profile { public TripProfile() { CreateMap<TripModel, Trip>() // 示例基础映射(实际可省略) .ForMember(dest => dest.Firstname, opt => opt.MapFrom(src => src.Firstname)) .ForMember(dest => dest.Lastname, opt => opt.MapFrom(src => src.Lastname)) // 疑问:如何同时处理两种场景? //.ForMember(dest => dest.ReasonForTrip, opt => opt.ConvertUsing(new TravelReasonConverter(), src => src.ReasonForTravel)) //.ForMember(dest => dest.ReasonForTrip, opt => opt.MapFrom(src => src.CustomTravelReason)); } }
解决方案
方法一:直接在MapFrom中编写条件逻辑
无需额外创建转换器,直接在MapFrom的委托中完成条件判断与转换:
public class TripProfile : Profile { public TripProfile() { CreateMap<TripModel, Trip>() .ForMember(dest => dest.Firstname, opt => opt.MapFrom(src => src.Firstname)) .ForMember(dest => dest.Lastname, opt => opt.MapFrom(src => src.Lastname)) .ForMember(dest => dest.ReasonForTrip, opt => opt.MapFrom(src => // 判断条件:ReasonForTravel有值且大于0 src.ReasonForTravel.HasValue && src.ReasonForTravel.Value > 0 // 满足条件时调用自定义转换器 ? new TravelReasonConverter().Convert(src.ReasonForTravel.Value, null, null) // 不满足时使用自定义原因 : src.CustomTravelReason)); } }
方法二:封装自定义转换器处理完整逻辑
如果逻辑较复杂或需要复用,可创建一个接收TripModel的自定义转换器,封装所有判断与转换逻辑:
// 自定义转换器:接收TripModel,返回对应的行程原因字符串 public class TripReasonConverter : IValueConverter<TripModel, string> { public string Convert(TripModel source, ResolutionContext context) { if (source.ReasonForTravel.HasValue && source.ReasonForTravel.Value > 0) { // 调用原有的TravelReasonConverter处理整数转字符串 var intConverter = new TravelReasonConverter(); return intConverter.Convert(source.ReasonForTravel.Value, null, null); } // 返回自定义原因 return source.CustomTravelReason; } } // 在Profile中配置使用该转换器 public class TripProfile : Profile { public TripProfile() { CreateMap<TripModel, Trip>() .ForMember(dest => dest.Firstname, opt => opt.MapFrom(src => src.Firstname)) .ForMember(dest => dest.Lastname, opt => opt.MapFrom(src => src.Lastname)) .ForMember(dest => dest.ReasonForTrip, opt => opt.ConvertUsing<TripReasonConverter>()); } }
内容的提问来源于stack exchange,提问作者marc_s
相关产品推荐
相关产品推荐

