为什么用AutoMapper创建的地图会随机消失?

本文关键字:随机 消失 地图 AutoMapper 创建 为什么 | 更新日期: 2023-09-27 18:09:38

我遵循这里使用的模式,但似乎它不适用于映射,除非我在映射发生之前直接调用AutoMapperWebConfiguration.Configure()

在我的印象中,AutoMapper的配置非常昂贵——如果我需要在每次调用之前调用Configure(),那么遵循这种模式的意义是什么?

AutoMapperWebConfiguration:

    public static class AutoMapperWebConfiguration
    {
        private static List<Profile> _profiles;
        public static void Configure(List<Profile> profiles)
        {
            _profiles = profiles;
            Configure();
        }
        public static void Configure()
        {
            Mapper.Initialize(cfg =>
            {
                foreach (var profile in GetProfiles())
                {
                    cfg.AddProfile(profile);
                }
            });
        }
        public static List<Profile> GetProfiles()
        {
            var profiles = new List<Profile>
            {
                new UserViewModelProfile(), new OrderViewModelProfile()
            };
            profiles.AddRange(_profiles);
            return profiles;
        }
    }
    public class UserViewModelProfile : Profile
    {
        protected override void Configure()
        {
            CreateMap<User, UserDetailViewModel>();
        }
    }
}

映射:

var userDetailViewModels = Mapper.Map<List<User>, List<UserDetailViewModel>>(users);

呼叫AutoMapperWebConfiguration.Configure()发生在Application_Start():

AutoMapperWebConfiguration.Configure(AutoMapperCoreConfiguration.GetProfiles());

当这个动作方法被加载时(映射出现的地方),我得到了异常:

缺少类型映射配置或不支持映射。

当我在映射发生之前直接调用AutoMapperWebConfiguration.Configure()时,这个就消失了。我做错了什么吗?

为什么用AutoMapper创建的地图会随机消失?

我猜在你的情况下,它不工作,因为你有映射配置实体和它的视图模型,但不为实体列表和视图模型列表。

我使用AutoMapper的方式如下:

  1. 有AutoMapperInitializer(在你的例子中是配置器)

    public static class AutoMapperInitializer {
        public static void Init() {
            // Your models maps goes here
            Mapper.CreateMap<RegisterViewModel, User>();
            Mapper.CreateMap<User, UserViewModel>().Bidirectional();
        }
        public static void Bidirectional<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression) {
            Mapper.CreateMap<TDestination, TSource>();
        }
    }
    
  2. 在Application_Start中,init方法被调用

    protected void Application_Start() {
        //...
        AutoMapperInitializer.Init();
    }
    
  3. 现在我可以在我的控制器代码中使用映射

    UserViewModel vm = Mapper.Map<UserViewModel>(user);
    

或列表

    [HttpPost]
    public JsonResult AjaxList() {
        IList<User> users = UserRepository.Find().ToList();
        IEnumerable<UserViewModel> vm = users.Select(u => Mapper.Map<UserViewModel>(u));
        return Json(vm);
    }

在我的所有地图都没有初始化的情况下出现看似随机的错误后,我偶然发现了这个问题。

我在我的Application_Start中调用Mapper.Initialize,但也在其他地方调用它作为创建地图的一种手段——我读到Initialize的性能比CreateMap好。

我没有意识到的是,每次调用Mapper.Initialize都会清除石板并删除之前创建的所有地图。一旦我删除了对Initialize的多个调用,我的问题就解决了。

希望这篇文章能帮助到像我这样只见树木不见森林的人。