Automapper更新EF Core集合实体时重复创建对象问题求助
解决AutoMapper更新EF Core集合时创建新对象的问题
临时忽略集合的方案
如果需要临时跳过集合映射、保留默认配置不变,可以在Map方法中通过IMappingOperationOptions指定忽略Features成员,之后再单独映射集合:
public async Task UpdateClient2(DTOClient dtoClient) { var efClient = await MyDbContext.Clients .Include(c => c.Features) .SingleOrDefaultAsync(c => c.Id == dtoClient.Id); // 临时忽略Features集合,仅更新Client的其他属性 mapper.Map(dtoClient, efClient, opt => opt.Ignore(c => c.Features)); // 单独更新Features集合 mapper.Map(dtoClient.Features, efClient.Features); }
修复默认映射让集合自动更新
你的核心问题是双向映射的EqualityComparison配置不完整:EFFeature到DTOFeature的映射加了匹配规则,但反向的DTOFeature到EFFeature映射未继承该规则,导致AutoMapper无法识别集合中已存在的对象,只能创建新实例。
修改映射配置,给反向映射也添加EqualityComparison:
CreateMap<EFFeature, DTOFeature>(MemberList.Destination) .EqualityComparison((efFeature, dtoFeature) => efFeature.Id == dtoFeature.Id) // 给反向映射补充匹配规则 .ReverseMap() .EqualityComparison((dtoFeature, efFeature) => dtoFeature.Id == efFeature.Id); CreateMap<EFClient, DTOClient>(MemberList.Destination) .ReverseMap();
也可以分开配置双向映射,逻辑更清晰:
// EF实体到DTO的映射 CreateMap<EFFeature, DTOFeature>(MemberList.Destination) .EqualityComparison((ef, dto) => ef.Id == dto.Id); // DTO到EF实体的映射,必须添加匹配规则 CreateMap<DTOFeature, EFFeature>(MemberList.Source) .EqualityComparison((dto, ef) => dto.Id == ef.Id); CreateMap<EFClient, DTOClient>(MemberList.Destination) .ReverseMap();
配置完成后,直接使用mapper.Map(dtoClient, efClient)或Persist方法,AutoMapper就能正确匹配集合中的对象,执行更新而非创建新实例:
public async Task UpdateClient2(DTOClient dtoClient) { var efClient = await MyDbContext.Clients .Include(c => c.Features) .SingleOrDefaultAsync(c => c.Id == dtoClient.Id); // 直接映射整个对象,集合会被正确更新 mapper.Map(dtoClient, efClient); } public async Task UpdateClient3(DTOClient dtoClient) { // Persist方法也能正确处理集合更新 await dbContext.Clients.Persist(mapper).InsertOrUpdateAsync(dtoClient); }
注意事项
- 确保查询时通过
Include(c => c.Features)加载了关联集合,EF Core需要跟踪这些实体才能执行更新操作。 EqualityComparison的匹配逻辑必须能唯一识别集合中的对象,此处用Id是合理选择,但要保证DTO和EF实体的Id值正确对应。
内容的提问来源于stack exchange,提问作者Mog0
相关产品推荐
相关产品推荐

