升级AutoMapper后遇到的“Missing map”与“Missing type map configuration”问题

前几天发现 AutoMapper 3.3 的一个性能问题(详见:遭遇AutoMapper性能问题:映射200条数据比100条慢了近千倍),因而将 AutoMapper 升级至最新的 5.1.1 看是否也存在这个性能问题。html

升级中想固然地将以前的map配置代码:app

Mapper.CreateMap<AEntity, ADto>();
Mapper.CreateMap<BEntity, BDto>();

改成:post

Mapper.Initialize(cfg => cfg.CreateMap<AEntity, ADto>());
Mapper.Initialize(cfg => cfg.CreateMap<BEntity, BDto>());

可是代码运行时在执行 Mapper.Map() 时出现下面的错误:性能

Missing type map configuration or unsupported mapping

在执行 ProjectTo() 时出现下面的错误:ui

System.InvalidOperationException: Missing map from AEntity to ADto. 
Create using Mapper.CreateMap<AEntity, ADto>.
在 AutoMapper.QueryableExtensions.ExpressionBuilder.CreateMapExpression...

当时百思不得其解,折腾了一段时间无果,就暂时放在一边。url

今天在博问上发现有人遇到了一样的问题——求解AutoMapper映射类发生错误求解,因而解决这个问题的兴趣被激发,又开始折腾。spa

在折腾的过程当中发现,若是不用 Mapper.Initialize() 这种静态的配置方式,改用下面的实例配置方式,就不会出现这个问题。code

var config = new MapperConfiguration(cfg => cfg.CreateMap<A, B>());
var mapper = config.CreateMapper();
mapper.Map<List<B>>(list);

Mapper.Initialize() 理所固然地成了最大的嫌疑对象,因而从 GitHub 上签出 AutoMapper 的源代码一看 Mapper.Initialize() 的实现,恍然大悟。htm

public static void Initialize(Action<IMapperConfigurationExpression> config)
{
    Configuration = new MapperConfiguration(config);
    Instance = new Mapper(Configuration);
}

原来每次调用 Mapper.Initialize() 都会建立新的 Mapper 实例,也就是屡次调用 Mapper.Initialize() 只有最后一次生效。对象

下面的配置代码中生效的只是第2行(BEntity到BDto的map),第1行(AEntity到ADto的map)没生效,从而出现前面所说的错误。

Mapper.Initialize(cfg => cfg.CreateMap<AEntity, ADto>());
Mapper.Initialize(cfg => cfg.CreateMap<BEntity, BDto>());

知道了缘由,解决起来就手到擒来,改成下面的代码便可。

var cfg = new MapperConfigurationExpression();
cfg.CreateMap<AEntity, ADto>();
cfg.CreateMap<BEntity, BDto>();
Mapper.Initialize(cfg);

解决这个问题后,成功完成了 AutoMapper 的升级,而后验证了 AutoMapper 3.3 的性能问题在 AutoMapper 5.1.1 中不存在。

相关文章
相关标签/搜索