AutoMapper搬运工之自定义映射
回顾
上节说到了AutoMapper的简单使用,对于复杂的Mapping需要强大的自定义,这节我们来看下AutoMapper的自定义Mapping(Projection)
搬运自Git:https://github.com/AutoMapper/AutoMapper/wiki/Projection
实例
本篇的场景是一个简单的日历事件,我们首先定义一个日历的事件如下:
1 public class CalendarEvent 2 { 3 //事件日期 4 public DateTime Date { get; set; } 5 //事件标题 6 public string Title { get; set; } 7 }
那么在页面,我们需要显示这个事件的具体信息,而且是可编辑的,定义一个ViewModel dto如下:
1 public class CalendarEventForm 2 { 3 //事件日期 4 public DateTime EventDate { get; set; } 5 //时间对应的小时 6 public int EventHour { get; set; } 7 //时间对应的分钟 8 public int EventMinute { get; set; } 9 //事件标题 10 public string Title { get; set; } 11 }
也许你会小小的纠结下,为啥要这么定义,页面上js直接转换之类的,好吧,这就是一个例子,你明白就好。
接下来和本系列一贯的做法一样,我们来看下手写Mapping的方式:
1 // 定义一个日历事件 2 var calendarEvent = new CalendarEvent 3 { 4 Date = new DateTime(2014, 12, 15, 20, 30, 0), 5 Title = "公司聚会" 6 }; 7 8 CalendarEventForm form = new CalendarEventForm 9 { 10 EventDate = calendarEvent.Date.Date, 11 EventHour = calendarEvent.Date.Hour, 12 EventMinute = calendarEvent.Date.Minute, 13 Title = calendarEvent.Title 14 };
这个Mapping依然很简单,没什么疑问,咱们来对比下使用AutoMapper:
1 // 配置Mapping 2 Mapper.CreateMap<CalendarEvent, CalendarEventForm>() 3 .ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.Date.Date)) 4 .ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.Date.Hour)) 5 .ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.Date.Minute)); 6 7 //Mapping 8 CalendarEventForm form = Mapper.Map<CalendarEvent, CalendarEventForm>(calendarEvent);
有什么感想?是不是感觉代码高大上,但是跟手写的没啥区别,哈哈,别着急,这只是一个例子。对于复杂的场景,你自然会体会到AutoMapper使代码简洁,配置统一。
说道配置这里需要说明一下:Mapping的配置并不是这样每次都要Create的,具体的说明,请期待下篇 《AutoMapper之配置》
回到上面的代码,我们来进一步的说明下这个ForMember
ForMember函数
AutoMapper提供了相关的API来支持自定义的Mapping配置,并且他支持lamda哦。
看一下ForMember的定义:
1 IMappingExpression<TSource, TDestination> ForMember(Expression<Func<TDestination, object>> destinationMember
第一个参数是目标属性,第二个参数是一定义的映射Expression, Expression让这个映射变得更加的动态,可以直接使用表达式或者干脆直接来个函数调用:
1 .ForMember(dest => dest.Title, opt => opt.MapFrom(src => ChangeTitle(src.Title));//调用方法 2 .ForMember(dest => dest.Title, opt => opt.MapForm(src => src.Title.Where(....);//表达式 3 4 string ChangeTitle(string title) 5 { 6 //自定义处理 7 ... 8 9 return "myName" + title; 10 }
有关Expression的内容及构造请参考表达式的文章,这里边的水很深,有机会我也去深入研究分享些内容。
细心的你或许会发现,如果映射写了多个会怎么样?经过测试,结论是:只有第一个配置是有效的,之后的同参数映射AutoMapper会自动忽略。
另外,还有一个ForMembers函数不过并不是很常用,其他的函数请自行研究,如果我有研究使用后面的系列我会一一分享。本节仍然是简单的内容,如果大家有更好的建议请留言,我觉得可能搬运的太简单,没有给人具体的映象的感觉。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?