升級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 中不存在。

相關文章
相關標籤/搜索