EF Core怎么设置列的默认值 EF Core HasDefaultValue方法

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