EF Core 7开启IDENTITY_INSERT后插入数据仍提示关闭的问题求助
问题解决:EF Core 7中IDENTITY_INSERT设置不生效的原因与方案
核心原因
IDENTITY_INSERT是数据库会话级别的设置,仅对当前连接会话有效。你之前用SqlQueryRaw执行SET IDENTITY_INSERT ON时,EF Core会创建一个独立的数据库连接/命令来执行这条语句,而后续的SaveChanges()会使用另一个新的连接会话,导致之前的IDENTITY_INSERT设置完全没作用。
解决方案
确保所有操作(开启IDENTITY_INSERT、插入数据、关闭IDENTITY_INSERT)都在同一个数据库连接会话中执行,以下是可行的代码实现:
using var transaction = await _context.Database.BeginTransactionAsync(); try { // 手动打开连接,强制后续操作复用同一个连接会话 await _context.Database.OpenConnectionAsync(); // 开启IDENTITY_INSERT(改用ExecuteSqlRawAsync,无需返回结果集) await _context.Database.ExecuteSqlRawAsync("SET IDENTITY_INSERT BobTable ON"); // 添加需要插入的实体数据 _context.BobTable.AddRange(yourEntityList); await _context.SaveChangesAsync(); // 关闭IDENTITY_INSERT await _context.Database.ExecuteSqlRawAsync("SET IDENTITY_INSERT BobTable OFF"); await transaction.CommitAsync(); } catch (Exception) { await transaction.RollbackAsync(); throw; } finally { // 手动关闭连接(可选,EF Core也会自动管理,但显式关闭更稳妥) if (_context.Database.CanConnect()) { await _context.Database.CloseConnectionAsync(); } }
关键注意点
- 必须使用
ExecuteSqlRawAsync而非SqlQueryRaw:SqlQueryRaw用于查询返回结果集,会触发独立的命令执行;ExecuteSqlRawAsync是无返回结果的执行,能确保在当前打开的连接中运行。 - 实体配置要对应:确认你的主键列已经正确配置了
[DatabaseGenerated(DatabaseGeneratedOption.None)]或ModelBuilder中的ValueGeneratedNever(),这是让EF Core主动插入主键值的必要条件。 - 事务的作用:包裹整个流程能保证操作的原子性,避免出现IDENTITY_INSERT意外开启未关闭的情况。
内容的提问来源于stack exchange,提问作者AndyW
相关产品推荐
相关产品推荐

