使用AutoMapper更新单字段时其余字段被置空的问题求助
AutoMapper更新单个字段时其余字段被置空的解决方案
我使用AutoMapper更新现有客户信息,但仅更新一个字段时,其余字段都会被置空。曾尝试使用ForAllOtherMembers方法,但该方法已被弃用,不清楚如何解决此问题。
更新方法代码
public async Task<ResponseModel> Update(CustomerDTO customer, int id) { ResponseModel responseModel = new ResponseModel(); try { Customer? existingCustomer = await _dbContext.FindAsync<Customer>(id); if (existingCustomer == null) { return new ResponseModel() { IsSuccess = false, Message = $"Customer doesn't exist!" }; } _mapper.Map(customer, existingCustomer); if (await _dbContext.SaveChangesAsync() > 0) { responseModel.Message = "Customer Updated Successfully"; responseModel.IsSuccess = true; } } catch (Exception ex) { responseModel.IsSuccess = false; responseModel.Message = $"Error:{ex.Message}"; } return responseModel; }
映射配置类代码
using AutoMapper; using static MGApi.Services.CustomerService; namespace MGApi.Models { public class CustomerProfile : Profile { public CustomerProfile() { CreateMap<CustomerDTO, Customer>(); } } }
Customer模型代码
using System.ComponentModel.DataAnnotations; namespace MGApi.Models { public class Customer { [Key] public int Id { get; set; } [Required] [StringLength(50)] [RegularExpression(@"^\d{10}$", ErrorMessage = "Invalid phone number")] public string? PhoneNumber { get; set; } [Required] [StringLength(50)] public string? Name { get; set; } [StringLength(100)] [EmailAddress] public string? Email { get; set; } [StringLength(10)] public string? Gender { get; set; } [DataType(DataType.Date)] public DateTime DateOfBirth { get; set; } public ICollection<CustomerData>? CustomerData { get; set; } } }
CustomerData模型代码
using System.ComponentModel.DataAnnotations; namespace MGApi.Models { public class CustomerData { [Key] public int Id { get; set; } public int CustomerId { get; set; } public double Sugar { get; set; } public double BP { get; set; } public double Height { get; set; } public double Weight { get; set; } public DateTime Timestamp { get; set; } = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("India Standard Time")); public Customer? Customer { get; set; } } }
解决方法
AutoMapper默认会将源对象中null或默认值的属性覆盖到目标对象上,导致仅更新单个字段时其他字段被置空。针对ForAllOtherMembers弃用的情况,可用以下两种方案解决:
方案1:显式映射需更新字段+忽略其余字段
如果仅需更新特定字段,直接配置映射规则,忽略未指定的字段:
public CustomerProfile() { CreateMap<CustomerDTO, Customer>() // 示例:仅映射PhoneNumber字段,根据实际需求添加需更新的字段 .ForMember(dest => dest.PhoneNumber, opt => opt.MapFrom(src => src.PhoneNumber)) // 忽略所有未显式配置的字段 .IgnoreAllOtherMembers(); }
方案2:添加条件判断,仅当源字段有有效值时映射
若需动态判断源字段是否为有效非空/非默认值再覆盖,给每个字段添加条件:
public CustomerProfile() { CreateMap<CustomerDTO, Customer>() .ForMember(dest => dest.PhoneNumber, opt => opt.Condition(src => !string.IsNullOrEmpty(src.PhoneNumber))) .ForMember(dest => dest.Name, opt => opt.Condition(src => !string.IsNullOrEmpty(src.Name))) .ForMember(dest => dest.Email, opt => opt.Condition(src => !string.IsNullOrEmpty(src.Email))) .ForMember(dest => dest.Gender, opt => opt.Condition(src => !string.IsNullOrEmpty(src.Gender))) .ForMember(dest => dest.DateOfBirth, opt => opt.Condition(src => src.DateOfBirth != default)); }
此方式仅在源字段存在有效内容时覆盖目标字段,保留目标对象原有其他字段值。
额外注意
- 需确保前端未误传空字符串或默认值到未更新字段,可在接口层添加校验过滤逻辑。
- 若业务中
default(DateTime)(即0001-01-01)是合法日期值,需调整DateOfBirth的条件判断逻辑,比如结合DTO的初始值或额外标识判断。
内容的提问来源于stack exchange,提问作者Tech2028
相关产品推荐
相关产品推荐

