You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AutoMapper两种Map调用的核心区别及PATCH接口失效原因解析

为什么修改AutoMapper调用后PATCH接口失效?

问题场景

原始可正常工作的PATCH接口代码:

[HttpPatch("{id}")]
public async Task<IActionResult> UpdateCity(int id, [FromBody] JsonPatchDocument<CityUpdateDto> patchDoc)
{
    var cityFromRepo = await _citiesRepository.GetCityById(id);
    var cityToPatch = _mapper.Map<CityUpdateDto>(cityFromRepo);

    Action<JsonPatchError> errorAction = error => { ModelState.AddModelError(error.Operation.path, error.ErrorMessage);};
    patchDoc.ApplyTo(cityToPatch, errorAction);
    // 有效代码:将修改后的DTO映射回已跟踪的实体
    _mapper.Map(cityToPatch, cityFromRepo);
    await _citiesRepository.SaveChangesAsync();

    return Ok("Done update");
}

修改后失效的代码:

[HttpPatch("{id}")]
public async Task<IActionResult> UpdateCity(int id, [FromBody] JsonPatchDocument<CityUpdateDto> patchDoc)
{
    var cityFromRepo = await _citiesRepository.GetCityById(id);
    var cityToPatch = _mapper.Map<CityUpdateDto>(cityFromRepo);

    Action<JsonPatchError> errorAction = error => { ModelState.AddModelError(error.Operation.path, error.ErrorMessage);};
    patchDoc.ApplyTo(cityToPatch, errorAction);
    // 无效代码:仅创建新实体,未更新原有跟踪实体
    _mapper.Map<City>(cityToPatch);
    await _citiesRepository.SaveChangesAsync();

    return Ok("Done update");
}

核心疑问:两种AutoMapper调用方式的差异是什么,为何修改后接口无法更新数据?


两种AutoMapper调用的本质区别

1. _mapper.Map(cityToPatch, cityFromRepo)(Map(TSource source, TDestination destination))

这是更新已有目标对象的调用方式:

  • 第一个参数是源数据对象(已经被Patch修改过的CityUpdateDto),第二个参数是已经存在的目标对象(从数据库获取的City实体,且处于EF Core上下文的跟踪状态)
  • AutoMapper会遍历源对象的属性,将对应值复制到目标对象的同名属性上
  • 由于目标对象cityFromRepo是EF Core正在跟踪的实体,属性的变更会被EF Core捕获,当调用SaveChangesAsync()时,EF Core会自动生成SQL UPDATE语句,将变更同步到数据库

2. _mapper.Map<City>(cityToPatch)(Map<TDestination>(TSource source))

这是创建全新目标对象的调用方式:

  • 该调用会以cityToPatch为数据源,创建一个全新的City类实例
  • 这个新创建的City对象完全独立于从数据库获取的cityFromRepo,也没有被EF Core上下文跟踪
  • 调用SaveChangesAsync()时,EF Core只会处理它正在跟踪的实体(也就是原来的cityFromRepo),而这个新对象的属性变更和原有实体毫无关系,因此数据库不会有任何更新

修改后接口失效的原因

修改后的代码仅通过AutoMapper创建了一个新的City对象,但没有将这个新对象的属性同步到EF Core正在跟踪的cityFromRepo上,也没有把新对象附加到EF Core上下文让其被跟踪。EF Core检测不到原有实体cityFromRepo的任何属性变更,所以调用SaveChangesAsync()时不会执行任何数据库更新操作,最终导致PATCH接口无法正常修改数据。

内容的提问来源于stack exchange,提问作者Akash Singh Rawat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:25:10