跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

C#怎么获取插入数据的自增ID_C#如何执行ExecuteScalar【必备】

ExecuteScalar 返回 null 并不表示插入失败,而是SQL未返回值或返回非标量结果;正确写法需用INSERT+SELECT SCOPE_IDENTITY()单语句,且须处理DBNull.Value及类型转换。 ExecuteScalar 返回 null 是不是没插进去? 不是。只要 sql 语句执行成功,
executescalar
就会返回结果——哪怕你写的是
insert into ...
但没加
select scope_identity()
,它就真返回
null
(或
dbnull.value
)。 c# 不会自动“猜”你要 id,必须显式要求。 常见错误现象:
ExecuteScalar()
返回
null
或抛出
InvalidCastException
,实际数据已写入数据库 根本原因:SQL 语句没返回值,或者返回了非标量结果(比如忘了用
SELECT
,只写了
INSERT
) 正确写法必须是单语句、单列、单行,例如:
INSERT INTO Users (Name) VALUES (@name); SELECT SCOPE_IDENTITY();
SCOPE_IDENTITY()
比
@@IDENTITY
安全,它只取当前作用域的最后自增 ID,不会被触发器干扰 为什么用 ExecuteScalar 而不是 ExecuteNonQuery + SELECT? 因为要避免两次往返数据库,也防止并发时 ID 被其他连接抢走。一次执行、原子获取,是最小安全窗口的做法。
ExecuteNonQuery
只返回影响行数(-1 表示不可用),完全不提供 ID 如果拆成两步:
ExecuteNonQuery
插入 → 再查
MAX(Id)
,在高并发下大概率拿错 ID(别人刚插了一条) SQL Server 支持语句拼接,但注意:不能用分号隔开两条独立语句再传给
ExecuteScalar
(会报错),必须让第二句是第一句的延续结果 PostgreSQL 用户请改用
RETURNING id
(如:
INSERT INTO users (name) VALUES (@name) RETURNING id
) 类型转换失败:int.Parse(ExecuteScalar()) 报错
ExecuteScalar()
返回的是
object
,可能为
null
或
DBNull.Value
,直接强转或
int.Parse
必崩。 错误现象:
System.InvalidCastException
或
System.ArgumentNullException
安全写法:先判断是否为
DBNull.Value
,再用
Convert.ToInt32()
(它能处理
null
和
DBNull
) 更推荐:用可空类型接收,例如
var id = cmd.ExecuteScalar() as int?;
,然后判空 别用
(int)cmd.ExecuteScalar()
—— 这种强制解包对
DBNull
直接炸 异步场景下该用 ExecuteScalarAsync 还是 QuerySingleAsync? 如果你用的是原生 ADO.NET,就用
ExecuteScalarAsync
;如果用了 Dapper,优先用
QuerySingleAsync
,语义更清晰、异常更明确。 C知道 CSDN推出的一款AI技术问答工具 下载
ExecuteScalarAsync
仍返回
object
,类型检查和转换逻辑得自己写 Dapper 的
QuerySingleAsync("INSERT ...; SELECT SCOPE_IDENTITY();")
会自动做类型验证,ID 为空时直接抛
NoRowsAffectedException
注意:Dapper 默认不支持多语句(除非开启
CommandBehavior.SequentialAccess
),SQL Server 需确保连接字符串含
MultipleActiveResultSets=True
才稳 EF Core 用户请直接用
SaveChanges()
后读取实体的 ID 属性,不用手动调
ExecuteScalar
事情说清了就结束。最常漏掉的是
DBNull.Value
判定和多语句执行时的连接配置,这两处一错,ID 就永远拿不到。

相关文章