AutoMapper映射EF实体时Id被设为0的问题排查咨询
问题原因及解决办法
问题出在操作流程错误,你的AutoMapper配置本身是正确的。
为什么Id变成0?
你当前的代码:
var character = await _context.FirstOrDefaultAsync(...); character = _mapper.Map<Character>(dto);
这里的_mapper.Map<Character>(dto)是创建一个全新的Character实例,而非更新你从数据库获取的现有实体。新实例的Id是int类型的默认值0,同时你原来从数据库拿到的带有效Id的character对象被新对象覆盖,所以最终Id变成0。
你配置的ForMember(dest => dest.Id, opt => opt.Ignore())是告诉AutoMapper:在映射时不要把dto的Id赋值给目标对象,但这个配置只在「更新现有对象」时生效,对「创建新对象」来说,目标对象的Id本来就是默认值,和Ignore配置无关。
正确的操作方式
要更新现有实体,需要使用AutoMapper的重载Map方法,将数据库获取的实体作为目标参数传入:
var character = await _context.FirstOrDefaultAsync(...); _mapper.Map(dto, character); // 将dto的值映射到已有的character对象上
这样执行后,AutoMapper会把dto中的Name、Health等属性值更新到现有character对象,同时因为配置了Ignore,Id属性会保留数据库获取的原始值,不会被修改。
补充说明
- 如果你用
Map<Character>(dto),无论怎么配置Ignore,新对象的Id都是默认值(int为0),因为这是创建新实例的行为 - 只有当你把现有对象作为目标传入Map方法时,Ignore配置才会起到「保留目标对象原有属性值」的作用
内容的提问来源于stack exchange,提问作者Ruben Hart
相关产品推荐
相关产品推荐

