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

.NET Core控制器已做实体存在检查仍报错,原因何在?

你的代码里有两个关键问题导致了这个错误:

1. 错误的存在性检查

_context.StudentGrades.Any()只是判断整个StudentGrades表是否有数据,完全不针对你要删除的id对应的记录。哪怕表不为空,这个判断也无法验证你通过FindAsync获取的studentGrades是否有效——比如在FindAsync执行后、Any()检查前,这条记录已经被其他操作删除,此时studentGrades会是null,但Any()仍会返回true,最终导致删除null实体或执行SaveChanges时报错。

2. 未处理并发删除/修改场景

即使你成功通过FindAsync获取到了记录,在调用Remove到SaveChangesAsync的这段时间里,这条记录可能被其他请求或进程删除/修改。EF Core执行删除操作时会检查数据库中是否存在目标记录,发现不存在就会抛出DbUpdateConcurrencyException。


修正方案

第一步:替换无效检查,先验证查询结果

把if(_context.StudentGrades.Any())改成直接检查studentGrades是否为null,确保要删除的记录确实存在:

[HttpDelete("{id}")]
public async Task<ActionResult<StudentGrades>> DeleteStudentGrades(string id)
{
    var studentGrades = await _context.StudentGrades.FindAsync(id);
    if (studentGrades == null)
    {
        return NotFound(); // 记录不存在,直接返回404
    }

    _context.StudentGrades.Remove(studentGrades);
    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        // 捕获并发异常后,重新查询数据库确认记录状态
        if (!_context.StudentGrades.Any(sg => sg.Id == id))
        {
            return NotFound(); // 记录已被其他操作删除,返回404
        }
        else
        {
            // 记录存在但被修改,根据业务需求返回冲突提示或其他响应
            return Conflict("该记录已被其他操作修改,删除失败");
        }
    }

    return studentGrades;
}

第二步:理解并发处理逻辑

  • 捕获DbUpdateConcurrencyException后必须重新查询数据库,因为之前的studentGrades是内存中的旧数据,无法反映当前数据库的真实状态。
  • 如果重新查询后记录不存在,说明是并发删除场景;如果存在,则是并发修改场景,可根据业务需求选择返回冲突提示、重试删除或其他处理方式。

可选:使用并发令牌优化并发控制

如果你的业务需要更严格的并发校验,可以给StudentGrades实体添加RowVersion属性(SQL Server对应timestamp类型),EF Core会自动用它检测并发修改:

public class StudentGrades
{
    public string Id { get; set; }
    // 其他业务属性...
    [Timestamp]
    public byte[] RowVersion { get; set; }
}

添加后,EF Core执行删除时会自动对比数据库中的RowVersion值与内存中的值,不一致则抛出并发异常,能更精准地检测到并发修改场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:45:39