Dapper怎么处理数据库默认值 Dapper插入时使用Default值

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

Dapper 本身不自动识别或处理数据库列的 DEFAULT 约束(比如

CREATE TABLE Users (Id INT IDENTITY, Name NVARCHAR(50), CreatedTime DATETIME2 DEFAULT GETDATE())
中的
DEFAULT GETDATE()
),它只是执行你写的 SQL。所以“插入时用数据库默认值”,关键在 SQL 写法参数传入逻辑,而不是 Dapper 自动帮你跳过字段。

显式省略字段,让数据库生效

最常用也最可靠的方式:在 INSERT 语句中 根本不写带 DEFAULT 的列,数据库自然会填入默认值。

✅ 正确写法(假设
Status
列有
DEFAULT 'Pending'
):
INSERT INTO Orders (UserId, OrderNumber) VALUES (@UserId, @OrderNumber)

Status
字段没出现,SQL Server / PostgreSQL 等都会自动用默认值。
❌ 错误写法:
INSERT INTO Orders (UserId, OrderNumber, Status) VALUES (@UserId, @OrderNumber, @Status)

即使你传
null
或空字符串,只要写了这列,Dapper 就会把参数值塞进去——覆盖默认值

用 DEFAULT 关键字显式指定

如果你必须在 SQL 中写出该列,又想强制走数据库默认值,可直接写

DEFAULT
字面量(注意不是参数):

✅ 支持写法(SQL Server / PostgreSQL 均支持):
INSERT INTO Orders (UserId, OrderNumber, Status) VALUES (@UserId, @OrderNumber, DEFAULT)
⚠️ 注意:
不能写成
@Status
参数再赋值为
DEFAULT
—— 参数只能是值,不能是关键字;
DEFAULT
必须硬编码在 SQL 字符串里。

实体类中跳过属性映射

如果用对象传参(如

db.Execute(sql, order)
),确保实体类中对应默认值的属性 不参与参数绑定

推荐做法:实体类中该属性不加 public set,或用
[JsonIgnore]
/ 自定义参数包装(如用
DynamicParameters
手动添加需要的字段);
避免陷阱:不要给默认列属性赋
null
default(T)
或空字符串,否则 Dapper 仍会把它当有效值传入。

批量插入(BulkCopy)时的默认值

使用

BulkCopy
(如
Dapper.ProviderTools
或原生
SqlBulkCopy
)时,默认值 默认不生效,因为它是绕过 SQL 引擎的底层导入。

✅ 解决方案:导入前先在 DataTable 或数据源中把默认列设为
DBNull.Value
,并确保目标表列设置为
AllowDBNull = true
且有 DEFAULT;
✅ 或者,在 BulkCopy 配置中启用
UseInternalTransaction
并配合
ColumnMappings
明确排除该列(部分驱动支持)。

基本上就这些。核心就一条:Dapper 不干预 SQL 语义,想用数据库默认值,就得让 SQL 本身“不提供值”或“明确写 DEFAULT”。

相关推荐