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# 对象。
