automapper需在启动时一次性配置并复用imapper实例;profile构造函数中注册createmap;formember需防null;集合映射须先配单类型;ef查询应使用projectto而非map;务必调用assertconfigurationisvalid()校验配置。

AutoMapper 不是“装完就能用”的函数式工具,必须在应用启动时完成一次性配置并复用 IMapper 实例;运行时反复 new MapperConfiguration 或在 Controller 里手写映射逻辑,大概率导致性能骤降、空引用异常或静默映射失败。
Profile 类必须在构造函数里写 CreateMap,别放别处
AutoMapper 只扫描 Profile 子类的构造函数体,其他位置(比如方法、字段初始化、静态构造器)写的 CreateMap<tsource tdestination>()</tsource> 全部被忽略。
- ✅ 正确:在
UserProfile : Profile的构造函数中调用CreateMap<userentity userdto>()</userentity> - ❌ 错误:把
CreateMap拆到单独方法里再从构造函数调用——AutoMapper 不会追踪方法调用链 - ⚠️ 注意:如果
Profile定义在独立类库中,AddAutoMapper(typeof(UserProfile).Assembly)必须显式传入该程序集,否则扫描不到
ForMember 映射字段名不一致时,lambda 参数要防 null
默认只匹配大小写不敏感的同名属性。一旦实体是 CreatedDate、DTO 是 CreatedAt,或者要取 User?.Id,就必须用 ForMember + MapFrom,且 lambda 中的源对象访问路径得带空值安全操作。
- ✅ 推荐:
.ForMember(dest => dest.UserId, opt => opt.MapFrom(src => src.User?.Id))—— 避免NullReferenceException - ❌ 危险:
.ForMember(dest => dest.UserId, opt => opt.MapFrom(src => src.User.Id))——src.User为 null 时直接崩 - ? 空值替代优先用
NullSubstitute("N/A"),而不是MapFrom(src => src.Name ?? "N/A"),后者绕过表达式树编译,高频列表映射时 GC 压力明显上升
集合映射失败?先确认单类型映射已注册
_mapper.Map<list>>(users)</list> 看似合理,但 AutoMapper 不会自动推导集合规则——它只基于你已声明的 CreateMap<userentity userdto>()</userentity> 来展开泛型。
- ✅ 正确顺序:先配
CreateMap<userentity userdto>()</userentity>,再调Map<list>></list> - ❌ 错误假设:“我配了单个类型,集合就该自动支持”——没配单类型映射,集合映射会静默返回空列表或抛
AutoMapperMappingException - ⚠️ 特别注意:
IEnumerable<t></t>和List<t></t>行为不同,若目标是IReadOnlyCollection<t></t>,需额外确认泛型约束是否兼容
EF 查询别用 Map,改用 ProjectTo 避免 N+1
对 IQueryable<userentity></userentity> 直接 Map<list>></list> 会强制执行查询、加载全部实体到内存,再做映射——完全失去 EF 的延迟加载和 SQL 投影优势。
- ✅ 正确做法:
context.Users.ProjectTo<userdto>(mapper.ConfigurationProvider)</userdto>—— 生成 SELECT 字段级投影 SQL,不查多余字段 - ❌ 错误写法:
context.Users.ToList().Select(x => mapper.Map<userdto>(x)).ToList()</userdto>—— 全量查库 + 内存遍历,DB 和 GC 双重压力 - ⚠️ 注意:
ProjectTo要求所有映射字段都能转成 Expression,所以MapFrom里不能有方法调用(如_repo.GetUserById()),也不能用复杂业务逻辑
最常被跳过的其实是 AssertConfigurationIsValid() —— 它不解决运行时逻辑错误,但能提前暴露类型未注册、嵌套映射缺失、只读属性无 setter 等配置硬伤。开发阶段漏掉这句,上线后字段为 null 往往要花半天排查。










