EF Core如何获取刚插入记录的ID EF Core获取自增ID方法

来源:这里教程网 时间:2026-02-21 17:34:23 作者:

EF Core 插入记录后直接获取自增 ID,核心就一点:调用

SaveChanges()
之后,实体对象的主键属性(如
Id
)会自动被赋值为数据库返回的自增数值
。不需要额外查询、不需要手动调用
SCOPE_IDENTITY()
,EF Core 在底层已通过数据库提供程序(如 SQL Server 的
OUTPUT INSERTED.*
或 MySQL 的
LAST_INSERT_ID()
)自动完成。

确保主键被正确识别为自增列

这是前提。EF Core 必须知道哪个字段是数据库自增主键,否则不会回填 ID:

默认约定:属性名是
Id
<classname>Id</classname>
(如
UserId
),且类型为
int
long
等整数类型时,EF Core 自动推断为自增标识列(SQL Server)或
AUTO_INCREMENT
(MySQL)
显式配置(推荐用于明确意图或避免歧义):
OnModelCreating
modelBuilder.Entity<User>().Property(e => e.Id).ValueGeneratedOnAdd();
若主键列名是
ID
但实际不是自增列,EF Core 仍可能误判——此时必须用
DatabaseGeneratedOption.None
显式禁用自动生成,否则插入会失败

插入后立即读取 ID 的标准写法

代码简洁、安全、无需额外操作:

创建实体并设置非主键字段 调用
Add()
加入上下文变更跟踪
调用
SaveChanges()
提交到数据库
紧接着读取实体的主键属性即可

示例:

var user = new User { Name = "Alice" };
context.Users.Add(user);
context.SaveChanges(); // ← 关键:执行后 user.Id 已被赋值
int newId = user.Id; // ✅ 此时就是刚插入的自增ID

常见问题与避坑点

以下情况会导致 ID 拿不到或报错,需特别注意:

SaveChanges() 前就读 ID:此时值仍是默认值(如 0),无效 主键属性被标记为
[DatabaseGenerated(DatabaseGeneratedOption.None)]
:EF 不会生成或回填 ID,必须自己赋值;若忘了赋值,会报“不能为 NULL”
使用了
AddRange()
但未检查返回值
:同样适用——每个实体的 ID 都会在
SaveChanges()
后自动填充
MySQL 连接字符串未启用
Allow User Variables=True
(旧版驱动)
:可能导致
LAST_INSERT_ID()
获取失败,建议升级 Pomelo.EntityFrameworkCore.MySql 到 7.0+ 或 Microsoft.Data.MySqlConnector

异步场景下用 SaveChangesAsync

和同步方式逻辑一致,只是语法稍不同:

AddAsync()
(可选,对单个实体非必需)
必须用
await SaveChangesAsync()
ID 在 await 完成后立即可用

示例:

var log = new CustomerLoginLog { CustomerId = 123, LoginTime = DateTime.Now };
context.LoginLogs.Add(log);
await context.SaveChangesAsync(); // ✅ 异步提交
int logId = log.Id; // ✅ 此时已赋值

基本上就这些。只要主键配置正确、按流程调用

SaveChanges()
(或异步版本),ID 就自然落在实体上——不复杂但容易忽略配置细节。

相关推荐