【发布时间】:2021-09-05 18:38:36
【问题描述】:
有人可以展示一个部分更新实体的示例吗? git/docs/stack 中的所有示例都只有 update 方法,它会替换所有字段,即使我发送 null。
看来我需要使用 HttpPatch 和 json-patch。但它有很多额外的代码......
用户实体
public class User: AbpUser<User>
{
[Required(AllowEmptyStrings = true)]
[StringLength(MaxNameLength)]
public override string Name { get; set; }
[Required(AllowEmptyStrings = true)]
[StringLength(MaxNameLength)]
public override string Surname { get; set; }
public string FatherName { get; set; }
public DateTime BirthDate { get; set; }
public long? DepartmentId { get; set; }
public long? ManagerId { get; set; }
public long? PositionId { get; set; }
public override string FullName => $"{Surname} {Name} {FatherName}";
}
CreateUserDto
{
"name": "Test",
"surname": "Test",
"emailAddress": "test@test.test"
}
UpdateUserDto
{
"id": 1,
"name": "Василий",
"surname": "Пупкин",
"fatherName": "Иванович",
"birthDate": "1993-02-21",
"emailAddress": "vasiliyp@test.test",
"phonenumber": "+79378889911",
"departmentId": 1,
"positionId" : 1
}
第二次UpdateUserDto
{
"id": 1,
"name": "Василий",
"surname": "Пупкин",
"fatherName": "Иванович"
}
第二次更新后,我想获得部分更新,但它会更新所有字段,包括我未发送的字段。例如,PositionId 将为 null,而不是 1。
用户应用服务
public override async Task<UserDto> UpdateAsync(UpdateUserDto input)
{
var user = await _userManager.GetUserByIdAsync(input.Id);
MapToEntity(input, user);
return await GetAsync(input);
}
protected override async void MapToEntity(UpdateUserDto input, User user)
{
ObjectMapper.Map(input, user);
user.SetNormalizedNames();
if (!user.DepartmentId.HasValue || user.DepartmentId == 0) return;
var department = await _departmentRepository.GetAsync((long)user.DepartmentId);
user.ManagerId = department.ManagerId;
}
更新
昨天我找到了一种方法:它需要自定义自动映射器来合并模型。
Configuration.Modules.AbpAutoMapper().Configurators.Add(
cfg => cfg.ForAllMaps((obj, cnfg) => cnfg.ForAllMembers(
opts => opts.Condition((src, dest, srcMember) => srcMember != null))));
但是有问题:
- DTO 中的所有值类型都必须可以为空,因为自动映射器将获取默认值。
- 尽管我已将 DateTime 定义为可为空,但自动转换会将其转换为默认值 (DateTime)。我还没有找到不用拐杖解决这个问题的方法。
if(input.BirthDate == null) input.BirthDate = user.BirthDate;
更新 2
[AutoMapTo(typeof(User))]
public class UpdateUserDto : EntityDto<long>
{
[StringLength(AbpUserBase.MaxNameLength)]
public string Name { get; set; }
[StringLength(AbpUserBase.MaxSurnameLength)]
public string Surname { get; set; }
public string FatherName { get; set; }
public DateTime? BirthDate { get; set; }
[EmailAddress]
[StringLength(AbpUserBase.MaxEmailAddressLength)]
public string EmailAddress { get; set; }
public string PhoneNumber { get; set; }
public long? DepartmentId { get; set; }
public long? PositionId { get; set; }
}
【问题讨论】: