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

时间:2014-06-19 20:46:08

标签: c# asp.net-mvc automapper

我正在关注pattern used here,但似乎它不适用于映射,除非我在映射之前直接调用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()时,这会消失。我做错了吗?

2 个答案:

答案 0 :(得分:0)

我想在你的情况下,它不起作用,因为你为实体及其视图模型配置了映射,但没有为实体列表和视图模型列表配置。

我通过以下方式使用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);
    
  4. 或列表

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

    希望它会有所帮助。

答案 1 :(得分:0)

看似随意的错误,我的地图都没有初始化,我偶然发现了这个问题。

我在我的Mapper.Initialize中呼叫Application_Start,但也在其他地方调用它作为创建地图的方法 - 我读过Initialize的性能优于{CreateMap 1}}。

我没有意识到,每次拨打Mapper.Initialize都会清除平板并删除之前创建的所有地图。一旦我删除了对Initialize的多个调用,我的问题便消失了。

希望这有助于其他人,像我这样的人无法看到森林中的树木。