AutoMapper使用ProjectTo时如何用switch表达式替代三元运算符?
解决方案
方案1:直接在MapFrom中使用switch表达式(推荐)
AutoMapper 10.0及以上版本原生支持将C# switch表达式转换为合法的表达式树,搭配EF Core 3.0及以上版本可以正常被解析为SQL的CASE WHEN语句,完全适配ProjectTo<>投影需求,直接按你想要的写法写即可:
CreateMap<TrophyTransfer, TrophyTransferSaveDto>() .ForMember(dest => dest.ReceiverName, opt => opt.MapFrom(src => src.ReceiverType switch { TrophyOwnerTypes.ExhibitionMuseum => src.ExhibitionMuseum!.Name, TrophyOwnerTypes.TaxidermyWorkshop => src.TaxidermyWorkshop!.Name, _ => src.Owner!.Name }));
如果判断分支达到5-6个,这种写法的可读性远高于嵌套三元表达式,维护起来也更简单。
方案2:抽离公共映射表达式
如果多个映射配置都需要用到这个取值逻辑,可以把表达式单独抽成静态字段复用,也能让映射配置文件更简洁:
// 单独定义复用的表达式 private static readonly Expression<Func<TrophyTransfer, string>> GetReceiverName = transfer => transfer.ReceiverType switch { TrophyOwnerTypes.ExhibitionMuseum => transfer.ExhibitionMuseum!.Name, TrophyOwnerTypes.TaxidermyWorkshop => transfer.TaxidermyWorkshop!.Name, // 新增分支只需要在这里加即可 _ => transfer.Owner!.Name }; // 映射配置中直接引用 CreateMap<TrophyTransfer, TrophyTransferSaveDto>() .ForMember(dest => dest.ReceiverName, opt => opt.MapFrom(GetReceiverName));
方案3:兼容旧版本的对齐写法
如果使用的AutoMapper版本较低不支持switch表达式转表达式树,可以把嵌套三元表达式按分支换行对齐,可读性也能大幅提升:
CreateMap<TrophyTransfer, TrophyTransferSaveDto>() .ForMember(dest => dest.ReceiverName, opt => opt.MapFrom(src => src.ReceiverType == TrophyOwnerTypes.ExhibitionMuseum ? src.ExhibitionMuseum!.Name : src.ReceiverType == TrophyOwnerTypes.TaxidermyWorkshop ? src.TaxidermyWorkshop!.Name : src.Owner!.Name));
注意:不要使用接收
Func委托的MapFrom重载,委托无法转换为表达式树,会导致ProjectTo<>无法解析,必须使用接收Expression<Func<>>表达式树参数的重载,以上三种方案均符合该要求。
内容的提问来源于stack exchange,提问作者AliReza Sabouri
相关产品推荐
相关产品推荐

