AutoMapper:MapFrom和ResolveUsing有什么区别?

忽略ResolveUsing重载,并且只考虑这两种方法:

void ResolveUsing(Func<TSource, object> resolver);
void MapFrom<TMember>(Expression<Func<TSource, TMember>> sourceMember);

这两者之间的主要区别似乎是ResolveUsing采用Func<TSource, object> ,而MapFrom采用Expression<Func<TSource, TMember>>

然而,在实际使用lambda表达式的客户端代码中,它们似乎是可以互换的:

Mapper.CreateMap<SourceType, DestType>() // uses ResolveUsing
   .ForMember(d => d.DestPropX, o => o.ResolveUsing(s => s.SourcePropY));

Mapper.CreateMap<SourceType, DestType>() // uses MapFrom
   .ForMember(d => d.DestPropX, o => o.MapFrom(s => s.SourcePropY));

那么,最终的两个选择之间的区别是什么? 一个比另一个快吗? 一个是比另一个更好的选择,如果是的话,何时/为什么?


在过去,我与Automapper的作者在邮件列表上进行了长时间的电子邮件交换。 MapFrom将通过表达式完成空检查:

所以你可以做opt => opt.MapFrom(src => src.SomeProp.Way.Down.Here.Somewhere)并且每个关卡都会被检查为null(因为它已经用于展平)。


我刚刚使用新的C#6空条件运算符做了一些基准测试?.

考虑以下情况:类A有一个子类B ,它有一个子C ,我们想要将其Name属性平铺到DTO中。 我测试了两个变体:

// using mapfrom
CreateMap<MapFromA, MapFromADto>()
    .ForMember(dto => dto.Name, o => o.MapFrom(a => a.B.C.Name));

// using resolveusing with elvis
CreateMap<ResolveUsingX, ResolveUsingXDto>()
    .ForMember(dto => dto.Name, o => o.ResolveUsing(x => x.Y?.Z?.Name));

我调用_mapper.Map<ResolveUsingXDto>(x);_mapper.Map<MapFromADto>(a); 为1000个不同的ResolveUsingX xMapFromA a并花费了时间使用System.Diagnostics.StopWatch 。 这是我的结果:

Distinct elements per batch: 1000; # batches for average: 25

A->B->C.Name, C is never null.
MapForm - average time taken for 1000x: 5527,84 ticks = 1,44 ms.
ResolveUsing - average time taken for 1000x: 5479,76 ticks =  1,4 ms.

A->B->C.Name, C is null 1/3 of the time.
MapForm - average time taken for 1000x: 72924,4 ticks = 27,44 ms.
ResolveUsing - average time taken for 1000x: 5351,2 ticks =  1,48 ms.

A->B->C.Name, C is null 1/2 of the time.
MapForm - average time taken for 1000x: 107016,92 ticks = 40,52 ms.
ResolveUsing - average time taken for 1000x: 5835,32 ticks =  1,56 ms.

A->B->C.Name, C is null 2/3 of the time.
MapForm - average time taken for 1000x: 141437,96 ticks = 53,64 ms.
ResolveUsing - average time taken for 1000x: 5789,72 ticks =  1,56 ms.

MapFrom必须捕获NullReferenceExceptions,这比使用elvis操作符的ResolveUsing?.


MapFrom有一些额外的智慧。 例如(来自邮件列表):

在MapFrom中,我试图聪明地挖掘儿童属性(很像正常的扁平化)。 MapFrom试图模仿扁平化,并增加了一些允许重定向的功能。 ResolveUsing没有这种行为。

我不确定这是否完全记录在任何地方(除了源代码)。

链接地址: http://www.djcxy.com/p/37381.html

上一篇: AutoMapper: What is the difference between MapFrom and ResolveUsing?

下一篇: Automapper, mapping to a complex object