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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:37:14