Dapper的[ExplicitKey]特性作用是什么?
Dapper [ExplicitKey]特性的作用及你的示例分析
什么是[ExplicitKey]?
[ExplicitKey]是Dapper提供的特性,专门用来标记非自增的主键字段。它的核心作用是告诉Dapper:这个字段属于主键,但它的值需要由开发者手动传入,而非数据库自动生成(比如自增ID、序列生成的ID等)。
默认情况下,Dapper的逻辑是:
- 自动识别自增主键字段(比如SQL Server带
IDENTITY属性的列); - 执行
Insert操作时会忽略这个自增主键字段(不写到INSERT语句里); - 插入完成后自动执行
SCOPE_IDENTITY()这类语句,获取数据库生成的主键值返回给你。
但如果给字段加上[ExplicitKey],Dapper就会调整行为:它会把这个字段纳入INSERT语句的字段列表,要求你必须传入值,不会自动忽略它——因为这是你要手动指定的主键。
为什么你的示例里加不加特性SQL都一样?
看你给出的生成SQL:
exec sp_executesql N'insert into InvoiceDetail ([InvoiceID], [Detail]) values (@InvoiceID, @Detail); select SCOPE_IDENTITY() id',N'@Detail nvarchar(4000),@InvoiceID int',@Detail=N'Insert_Single_1',@InvoiceID=4
出现这种情况,大概率是因为InvoiceID并不是InvoiceDetail表的自增主键,甚至可能只是一个外键(关联Invoice表的字段)。
Dapper的主键识别逻辑是这样的:
- 优先找带
[Key]或[ExplicitKey]的字段当主键; - 如果没有特性,会按字段名(比如
Id、TableNameId)自动识别; - 只有当识别出的主键是自增类型时,Dapper才会在插入时忽略它并返回生成的ID。
在你的场景里:
InvoiceID不是自增主键,所以不管你加不加[ExplicitKey],Dapper都会把它当作普通字段处理,插入时自然会包含在INSERT语句中;- SQL末尾的
select SCOPE_IDENTITY(),说明你的InvoiceDetail表存在另一个自增主键字段(比如DetailID),Dapper自动识别到了这个自增主键,所以才会添加这条语句获取生成的ID——这个行为和InvoiceID是否加[ExplicitKey]完全无关。
举个正确的使用场景:假设你有一个Order表,主键是OrderNo(手动分配的订单编号,不是自增),这时候给OrderNo字段加上[ExplicitKey],Dapper插入时就会把OrderNo写入INSERT语句,不会忽略它,也不会额外执行SCOPE_IDENTITY()(除非表中还有其他自增字段)。
内容的提问来源于stack exchange,提问作者Serg
相关产品推荐
相关产品推荐

