AutoMapper搬运工之自定义映射

2022-12-14,,,

<!--
.hf-h2{background: #2B6695 !important;border-radius: 6px 6px 6px 6px !important;box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5);color: #FFFFFF;font-family: "微软雅黑" , "宋体" , "黑体" ,Arial;font-size: 17px;font-weight: bold;height: 25px;line-height: 25px;margin: 15px 0 !important;padding: 5px 0 5px 20px;text-shadow: 2px 2px 3px #222222;}.hf-line{text-indent: 2em;}
-->

回顾

上节说到了AutoMapper的简单使用,对于复杂的Mapping需要强大的自定义,这节我们来看下AutoMapper的自定义Mapping(Projection)

搬运自Git:https://github.com/AutoMapper/AutoMapper/wiki/Projection

实例

本篇的场景是一个简单的日历事件,我们首先定义一个日历的事件如下:

 public class CalendarEvent
{
//事件日期
public DateTime Date { get; set; }
//事件标题
public string Title { get; set; }
}

那么在页面,我们需要显示这个事件的具体信息,而且是可编辑的,定义一个ViewModel dto如下:

 public class CalendarEventForm
{
//事件日期
public DateTime EventDate { get; set; }
//时间对应的小时
public int EventHour { get; set; }
//时间对应的分钟
public int EventMinute { get; set; }
//事件标题
public string Title { get; set; }
}

也许你会小小的纠结下,为啥要这么定义,页面上js直接转换之类的,好吧,这就是一个例子,你明白就好。

接下来和本系列一贯的做法一样,我们来看下手写Mapping的方式:

 // 定义一个日历事件
var calendarEvent = new CalendarEvent
{
Date = new DateTime(, , , , , ),
Title = "公司聚会"
}; CalendarEventForm form = new CalendarEventForm
{
EventDate = calendarEvent.Date.Date,
EventHour = calendarEvent.Date.Hour,
EventMinute = calendarEvent.Date.Minute,
Title = calendarEvent.Title
};

这个Mapping依然很简单,没什么疑问,咱们来对比下使用AutoMapper:

 // 配置Mapping
Mapper.CreateMap<CalendarEvent, CalendarEventForm>()
.ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.Date.Date))
.ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.Date.Hour))
.ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.Date.Minute)); //Mapping
CalendarEventForm form = Mapper.Map<CalendarEvent, CalendarEventForm>(calendarEvent);

有什么感想?是不是感觉代码高大上,但是跟手写的没啥区别,哈哈,别着急,这只是一个例子。对于复杂的场景,你自然会体会到AutoMapper使代码简洁,配置统一。

说道配置这里需要说明一下:Mapping的配置并不是这样每次都要Create的,具体的说明,请期待下篇 《AutoMapper之配置》

回到上面的代码,我们来进一步的说明下这个ForMember

ForMember函数

AutoMapper提供了相关的API来支持自定义的Mapping配置,并且他支持lamda哦。

看一下ForMember的定义:

IMappingExpression<TSource, TDestination> ForMember(Expression<Func<TDestination, object>> destinationMember

第一个参数是目标属性,第二个参数是一定义的映射Expression, Expression让这个映射变得更加的动态,可以直接使用表达式或者干脆直接来个函数调用:

 .ForMember(dest => dest.Title, opt => opt.MapFrom(src => ChangeTitle(src.Title));//调用方法
.ForMember(dest => dest.Title, opt => opt.MapForm(src => src.Title.Where(....);//表达式 string ChangeTitle(string title)
{
//自定义处理
... return "myName" + title;
}

有关Expression的内容及构造请参考表达式的文章,这里边的水很深,有机会我也去深入研究分享些内容。

细心的你或许会发现,如果映射写了多个会怎么样?经过测试,结论是:只有第一个配置是有效的,之后的同参数映射AutoMapper会自动忽略。

另外,还有一个ForMembers函数不过并不是很常用,其他的函数请自行研究,如果我有研究使用后面的系列我会一一分享。本节仍然是简单的内容,如果大家有更好的建议请留言,我觉得可能搬运的太简单,没有给人具体的映象的感觉。

AutoMapper搬运工之自定义映射的相关教程结束。

《AutoMapper搬运工之自定义映射.doc》

下载本文的Word格式文档,以方便收藏与打印。