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

EF Core中显式与隐式事务下的SaveChanges()疑问

关于EF Core显式事务、SaveChanges()与存储过程的疑问解答

核心答案

  • FromSqlInterpolated调用的存储过程直接操作实际数据库,EF Core的上下文缓存(Change Tracker)管不到这类原生SQL请求的结果。
  • 你在未提交的显式事务里调用SaveChanges()后,存储过程能读到软删除变更,是因为当前数据库连接在事务中,能看到这个事务内的未提交修改。

具体拆解

  1. 显式事务里的SaveChanges()到底做了什么
    用DbContext.Database.BeginTransaction()开事务后,调用SaveChanges()会把软删除的变更写入数据库,但这些变更不会立刻持久化到磁盘——它们被事务“锁住”了,只有当前开启事务的这个数据库连接能看到这些修改,其他连接看不到。这是SQL Server事务的默认隔离规则(读已提交)。

  2. 存储过程为什么能读到这些变更
    你用FromSqlInterpolated调用存储过程时,EF Core会用当前上下文绑定的那个数据库连接(也就是开事务的那个)去执行存储过程。所以存储过程跑的时候,能读取到这个事务里还没提交的软删除标记,自然就能正常工作了。

  3. 不用显式事务为啥不行
    没开事务的话,两种情况都满足不了你的需求:

    • 只改上下文实体的软删除标记但不调用SaveChanges():这些修改只在EF的内存缓存里,数据库根本不知道,存储过程查不到;
    • 调用SaveChanges():修改直接提交到数据库了,存储过程能查到,但你没法回滚了——要是后续逻辑出问题,软删的记录没法恢复。

额外提醒

EF Core的Change Tracker只对LINQ查询(比如dbContext.Users.Where(u => !u.IsDeleted))生效,原生SQL、存储过程都是直接跟数据库打交道,完全绕开上下文缓存。这就是你必须用显式事务+同连接的方式,才能让存储过程读到未提交变更的原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:21:07