在Infrastructure项目中使用AutoMapper遇‘Missing type map configuration’错误
DB实体位于Infrastructure项目(采用数据库优先方案),DTO实体位于Application项目。尝试将DB实体映射为DTO实体时出现以下错误:
AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
Mapping types:
List1 -> UserDto System.Collections.Generic.List1[[RegionManagement.Persistence.ModelsDb.User, RegionManagement.Persistence, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> RegionManagement.Domain.Entities.Administration.UserEntries.UserDto
应用包含两处映射逻辑:Infrastructure项目中DB实体转DTO实体,Application项目中DTO实体转其他DTO/VM实体。添加Infrastructure中的映射前一切正常,已在Infrastructure项目中创建仓库类UserRepository、映射配置类MappingProfile,并通过InfrastructureServiceRegistration注册服务,且在Startup.cs中先后注册了Application和Infrastructure的服务,但扫描程序集配置AutoMapper后问题仍未解决。
UserRepository.cs
public class UserRepository : IUserRepository<UserDto> { protected readonly RegionManagementDbContext _dbContext; private readonly IMapper _mapper; public UserRepository(RegionManagementDbContext dbContext, IMapper mapper) { _dbContext = dbContext; _mapper = mapper; } public async Task<IReadOnlyList<UserDto>> ListAllAsync() { var dbDataList = await _dbContext.Users.ToListAsync(); var mapList = _mapper.Map<UserDto>(dbDataList); return (IReadOnlyList<UserDto>)mapList; } }
MappingProfile.cs
public class MappingProfile : Profile { public MappingProfile() { CreateMap<User, UserDto>(); } }
InfrastructureServiceRegistration.cs
public static class InfrastructureServiceRegistration { public static IServiceCollection AddPersistenceServices(this IServiceCollection services, IConfiguration configuration) { services.AddDbContext<RegionManagementDbContext>(options => options.UseSqlServer(configuration.GetConnectionString("RegionManagementConnectionString"))); services.AddAutoMapper(Assembly.GetExecutingAssembly()); services.AddScoped<IUserRepository<UserDto>, UserRepository>(); return services; } }
Startup.cs
public void ConfigureServices(IServiceCollection services) { services.AddApplicationServices(); services.AddInfrastructureServices(Configuration); services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "RegionManagement.Api", Version = "v1" }); }); }
修正映射调用的目标类型
错误核心是代码试图将List<User>映射为单个UserDto,但仅配置了User到UserDto的单实体映射。AutoMapper支持自动处理集合映射,只需将映射目标改为集合类型:
修改UserRepository的ListAllAsync方法:public async Task<IReadOnlyList<UserDto>> ListAllAsync() { var dbDataList = await _dbContext.Users.ToListAsync(); return _mapper.Map<IReadOnlyList<UserDto>>(dbDataList); }无需强制类型转换,AutoMapper会直接返回正确的集合类型。
确保AutoMapper扫描所有映射配置程序集
当前Infrastructure项目仅扫描自身程序集的映射配置,但Application项目也存在映射逻辑。需在注册AutoMapper时同时包含两个项目的程序集:
修改InfrastructureServiceRegistration中的AddAutoMapper调用:// 替换原AddAutoMapper调用,传入Application和Infrastructure的程序集 services.AddAutoMapper( typeof(Application项目中任意MappingProfile类型).Assembly, Assembly.GetExecutingAssembly() );或在
Startup.cs中统一注册AutoMapper,覆盖两处注册:// 在ConfigureServices中添加,扫描所有程序集的映射配置 services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());添加映射配置验证
可在启动时验证AutoMapper配置,提前发现未配置的映射:
在Startup.cs的ConfigureServices末尾添加:var mapper = services.BuildServiceProvider().GetRequiredService<IMapper>(); mapper.ConfigurationProvider.AssertConfigurationIsValid();
内容的提问来源于stack exchange,提问作者mustafa00

