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

EntityFramework 6.0.0提交含空数组的JSON时子集合对象被移除问题

问题原因
  • AutoMapper默认集合映射策略:对已有目标对象执行集合属性映射时,默认直接用源对象的集合完整替换目标对象的集合,不会做差量合并。你传入的请求体中photos是空数组,映射时直接将查询到的主实体关联的Photos集合替换为了空数组。
  • Entity Framework 跟踪行为:你查询主实体时通过Include("Photos")加载了关联的照片实体,这些实体处于上下文跟踪状态。当Photos导航属性被替换为空数组后,EF会判定原有关联的照片实体已和主实体解除关联:如果外键设置了级联删除,或者Photos是主实体的所属实体(Owned Entity),EF执行SaveChanges时会直接删除这些旧的照片数据,最终导致数据库中关联的照片被清空。
  • 此前未触发的常见原因:大概率是之前的查询逻辑没有加Include("Photos"),未加载的导航属性处于未填充状态,AutoMapper赋值空数组后,EF不知道数据库中存在关联的照片数据,不会执行删除操作;也可能是之前的AutoMapper配置针对集合属性设置了映射条件,后续配置被修改,或者JSON序列化配置调整后,原本会被忽略的空数组现在可以正常传递到后端。
解决思路

根据你的业务需求选择对应方案即可:

场景1:不允许传入空数组清空原有照片数据

方案1:修改AutoMapper映射配置

为Photos属性添加映射条件,仅当源对象的Photos集合非空且包含元素时才执行映射:

// 在你的AutoMapper Profile配置类中添加规则
CreateMap<RequestViewModel, Request>()
    .ForMember(dest => dest.Photos, opt => 
        opt.Condition((src, dest) => src.Photos != null && src.Photos.Any()));

方案2:手动处理集合映射逻辑

自动映射时忽略Photos属性,自行实现集合的差量更新逻辑,可灵活控制新增、修改、删除的规则:

public ActionResult Update([FromBody] RequestViewModel body)
{
  using (var dbContext = new PrimaryDbContext())
  {
    var data = dbContext.Set<Request>().Include("Photos").Where(r => r.Id == body.Id).FirstOrDefault();
    if(data == null) return NotFound();
    
    // 映射时忽略Photos属性
    Mapper.Map(body, data, opt => opt.ForMember("Photos", opt => opt.Ignore()));

    // 手动处理照片集合更新
    if (body.Photos != null)
    {
        // 示例:删除请求体中不存在的旧照片
        var toDeletePhotos = data.Photos
            .Where(p => !body.Photos.Any(bp => bp.Id == p.Id))
            .ToList();
        foreach (var photo in toDeletePhotos)
        {
            data.Photos.Remove(photo);
        }
        // 按需新增/更新照片的逻辑
    }

    dbContext.SaveChanges();
    return Ok(data);
  }
}

场景2:支持传入空数组清空照片,仅需确认当前行为符合预期

当前逻辑没有问题,属于EF和AutoMapper的默认协同行为,无需额外修改。


内容的提问来源于stack exchange,提问作者aj go

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:36:03