Dapper 获取 MySQL 自增 ID 的正确方式是 INSERT 后立即用同一连接(推荐加事务)执行 SELECT LAST_INSERT_ID() 并用 ExecuteScalar 获取结果;多语句优化需开启 Allow User Variables;不可依赖 Execute 返回值或 OUTPUT 子句。
Dapper 本身不直接封装 MySQL 的 LAST_INSERT_ID(),但它能通过标准 SQL 执行和返回值机制,安全、高效地获取刚插入记录的自增 ID。关键在于:使用 ExecuteScalar 执行带 SELECT LAST_INSERT_ID() 的语句,或更推荐——在单条语句中用 INSERT ...; SELECT LAST_INSERT_ID()(MySQL 支持多语句)或直接依赖 Dapper 对 ExecuteScalar 插入语句的隐式行为(需配
置)。
这是最清晰、兼容性最好的方式。先执行 INSERT,再立即执行 SELECT LAST_INSERT_ID(),确保在同一个连接和事务上下文中运行:
IDbConnection 实例(不能新开连接)LAST_INSERT_ID() 是连接级变量,只要没被其他 INSERT 覆盖,就安全示例代码:
using var conn = new MySqlConnection(connStr);
conn.Open();
using var tx = conn.BeginTransaction();
try
{
conn.Execute("INSERT INTO users (name, email) VALUES (@Name, @Email)",
new { Name = "Alice", Email = "a@example.com" }, tx);
var id = conn.ExecuteScalar("SELECT LAST_INSERT_ID()", transaction: tx);
tx.Commit();
Console.WriteLine($"新用户ID:{id}");
}
catch
{
tx.Rollback();
throw;
}
MySQL 支持在一个命令中执行多条语句(需连接字符串启用 Allow User Variables=True 或默认允许),Dapper 可用 ExecuteScalar 直接运行 INSERT; SELECT LAST_INSERT_ID():
Allow User Variables=True(部分驱动版本需要)示例:
var sql = @"INSERT INTO users (name, email) VALUES (@Name, @Email); SELECT LAST_INSERT_ID();";
var id = conn.ExecuteScalar(sql, new { Name = "Bob", Email = "b@example.com" });
某些 MySQL 驱动(如较新版本的 MySqlConnector)在调用 Execute 插入后,会将自增 ID 自动设为返回值(类似 SQL Server 的 @@IDENTITY)。但 Dapper 的 Execute 方法本身只返回影响行数(int),**不会自动返回 ID** ——除非你用 ExecuteScalar 或驱动扩展了行为。
Execute(...) 的返回值作为 ID(它返回的是“1”,不是 ID)Execute 得到 ID,大概率是用了自定义扩展方法或特定驱动的非标行为LAST_INSERT_ID()
SQL Server 支持 OUTPUT INSERTED.Id,但 MySQL **没有等效语法**。别尝试写 INSERT ... OUTPUT,会报语法错误。必须用 LAST_INSERT_ID() 方案。
基本上就这些。核心就一条:INSERT 后立刻用同一连接(最好同事务)执行 SELECT LAST_INSERT_ID(),用 ExecuteScalar 拿结果。不复杂但容易忽略连接复用和事务边界。