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

EF使用FirstOrDefault后SaveChanges返回2 Sal表产生重复记录问题

问题说明

实现用户记录更新功能时,通过FirstOrDefault()获取匹配UserName的第一条记录q后调用SaveChanges()方法,出现以下异常表现:

  • 已确认数据库中仅存在1条匹配的待更新记录
  • SaveChanges()返回的受影响行数success为2,不符合预期值1
  • 执行完成后Sal表中出现2条重复记录
    需要调整查询与更新逻辑,正确完成单条记录的更新操作。

原有问题代码

public static bool UpdateUser(User user)
{
    try
    {
        var q = db.Users.Where(x => x.UserName == user.UserName).FirstOrDefault();

        if (q != null)
        {
            q.Password = user.Password;
            db.Users.Update(user);
            int success = db.SaveChanges();
            if (success == 1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        return false;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}
问题根因

问题和FirstOrDefault()查询逻辑无关,是重复提交实体更新导致的:

  1. 调用FirstOrDefault()查询到的实体q会被EF Core的变更追踪器自动跟踪,修改q.Password属性后,EF已经自动将q标记为待更新状态
  2. 后续调用db.Users.Update(user)时,传入的是方法参数中的user对象,该对象未被当前上下文追踪,EF会将其作为独立实体附加到上下文并标记为待写入状态。如果user对象的主键值未被EF正确识别,EF会将其判定为新记录执行插入操作
  3. 执行SaveChanges()时,EF会同时处理两个实体的写入操作:一条是跟踪到的q的更新,一条是user的插入/更新,因此返回受影响行数为2,同时出现重复数据。
修复方案

保留原有先查询再更新的逻辑即可,删除多余的db.Users.Update(user)调用,EF变更追踪器会自动感知已查询实体的属性修改,SaveChanges()只会生成单条更新SQL,返回受影响行数为1。
修复后代码如下:

public static bool UpdateUser(User user)
{
    try
    {
        var q = db.Users.FirstOrDefault(x => x.UserName == user.UserName);
        if (q != null)
        {
            q.Password = user.Password;
            // 移除多余的手动Update调用,EF自动跟踪已查询实体的属性变更
            int success = db.SaveChanges();
            return success == 1;
        }
        return false;
    }
    catch (Exception)
    {
        throw; // 注意不要使用throw ex,会丢失原始异常调用堆栈,直接throw即可保留完整异常信息
    }
}

补充说明:如果要使用db.Users.Update()方法做离线实体更新,不需要提前查询数据库,直接传入主键匹配的实体调用Update再SaveChanges即可,不要同时混用跟踪查询修改+手动Update的写法,避免重复提交变更。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 20:57:12