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