结合泛型仓储模式实现AutoMapper时的类型映射问题排查
解决泛型仓储模式中AutoMapper未生效的EF实体类型错误
首先咱们拆解下你遇到的错误:the entity type ArticleType is not part of the model for the current context,本质原因很直白——你的BaseRepository.Add()方法接收到的是API层的ArticleType,但EF的BlogDBContext只认DAL层的ArticleType,这俩虽字段完全一致,但属于不同命名空间的独立类型,EF自然不识别。你之前在APIMapperConfig里只是配置了映射规则、做了一次测试调用,但实际业务流程里根本没执行类型转换,就直接把API模型传给了仓储。
下面是具体解决方案,分步骤落地:
1. 修正AutoMapper配置(更规范可靠)
先调整映射配置,加上配置验证,提前发现映射规则错误:
public static class APIMapperConfig { static MapperConfiguration adminConfig; public static IMapper adminMapper; public static void Configure() { ConfigureAdminConfiguration(); } public static void ConfigureAdminConfiguration() { adminConfig = new MapperConfiguration(cfg => { // 明确配置API到DAL的映射关系 cfg.CreateMap<API.ArticleType, DAL.ArticleType>(); // 如果需要从DAL实体转回API模型,可添加反向映射 // cfg.CreateMap<DAL.ArticleType, API.ArticleType>(); }); // 验证映射配置是否合法,有问题直接抛出异常 adminConfig.AssertConfigurationIsValid(); adminMapper = adminConfig.CreateMapper(); } }
2. 调整泛型基控制器,加入类型转换逻辑
你的BaseController<T>里的T是API模型,但仓储需要的是DAL实体,所以让基控制器同时支持两个泛型参数(API模型+DAL实体),在Add方法中完成类型转换:
public class BaseController<TModel, TEntity> : ApiController where TEntity : class { private readonly IBaseRepository<TEntity> _repository; public BaseController() { _repository = UnityConfig.ResolveObject<IBaseRepository<TEntity>>(); } [HttpPost] public void Add(TModel item) { // 用AutoMapper将API模型转换为DAL实体 var entity = APIMapperConfig.adminMapper.Map<TModel, TEntity>(item); _repository.Add(entity); } }
接着修改ArticleTypeController,指定对应的泛型参数:
public class ArticleTypeController : BaseController<API.ArticleType, DAL.ArticleType> { // 专属业务逻辑可在这里扩展 }
3. (可选优化)用依赖注入替代静态AutoMapper
静态类虽简单,但不利于测试和扩展,推荐把IMapper注册到Unity容器,通过构造函数注入到基控制器:
首先在UnityConfig中添加注册:
public static class UnityConfig { public static void RegisterTypes(IUnityContainer container) { // 注册AutoMapper的IMapper实例 container.RegisterInstance<IMapper>(APIMapperConfig.adminMapper); // 其他依赖注册... container.RegisterType<IBaseRepository<DAL.ArticleType>, BaseRepository<DAL.ArticleType>>(); container.RegisterType<IArticleTypeServices, ArticleTypeServices>(); } }
然后修改基控制器的构造函数注入:
public class BaseController<TModel, TEntity> : ApiController where TEntity : class { private readonly IBaseRepository<TEntity> _repository; private readonly IMapper _mapper; // 通过构造函数注入依赖,符合依赖注入原则 public BaseController(IBaseRepository<TEntity> repository, IMapper mapper) { _repository = repository; _mapper = mapper; } [HttpPost] public void Add(TModel item) { var entity = _mapper.Map<TModel, TEntity>(item); _repository.Add(entity); } }
这样调整后,当你用Fiddler请求添加接口时,API层接收的ArticleType会被AutoMapper转换成DAL层实体,再传给仓储,EF就能正确识别并写入数据库了。
内容的提问来源于stack exchange,提问作者Dheeraj Kumar
相关产品推荐
相关产品推荐

