EF Core 的 HasDefaultValue 是让数据库在插入时自动填充未指定字段的默认值,通过迁移生成 CREATE TABLE 或 ALTER TABLE 语句将 DEFAULT 约束写入数据库;仅当 C# 实体未赋值该属性时生效,且只支持常量值,动态值需用 HasDefaultValueSql。

EF Core 设置列默认值,核心是让数据库在插入数据时自动填充未指定的字段。关键不在于 C# 层面赋值,而在于告诉数据库“这个列缺值时该填什么”。HasDefaultValue 就是做这件事的——它把默认值写进数据库表结构里,由数据库执行,不是 EF Core 在内存里帮你填。
什么时候 HasDefaultValue 生效
它只在数据库层面起作用,且只在以下两种迁移操作中生成对应 SQL:
- 首次创建表:生成
CREATE TABLE ... MyColumn INT DEFAULT 100 - 给已有表新增列:生成
ALTER TABLE ... ADD MyColumn INT DEFAULT 100,并自动为历史行补上默认值
怎么配置 HasDefaultValue
在 OnModelCreating 中用 Fluent API 配置:
modelBuilder.Entity
.Property(p => p.Price)
.HasDefaultValue(0.0m);
支持常见类型:数值、字符串(如 "Unknown")、布尔(true)、日期(DateTime.Today)等。注意:传入的是常量值,不是表达式。
HasDefaultValue 和 HasDefaultValueSql 的区别
前者填固定值,后者填数据库运行时计算的值:
-
.HasDefaultValue(DateTime.UtcNow)→ 写死一个时间点(迁移生成时的时间) -
.HasDefaultValueSql("GETUTCDATE()")→ 每次插入都取当前数据库时间
像自动时间戳、随机 GUID、序列号等动态场景,必须用 HasDefaultValueSql。
插入数据时它怎么工作
EF Core 不会主动把默认值写进实体对象,也不在 SaveChanges 前自动赋值。它的行为很明确:
- 你没给属性赋值 → EF Core 插入语句里不包含该列 → 数据库用 DEFAULT 填
- 你显式赋了值(哪怕赋 null 或 0)→ EF Core 把这个值写进 INSERT → 覆盖数据库默认值
所以它真正起效的前提是:代码里“不碰”那个属性。
基本上就这些。不复杂但容易忽略:它管的是数据库,不是你的 C# 对象。










