Entity Framework中HasDefaultValueSql与ValueGeneratedOnAdd配置未按预期生效
问题原因分析
你遇到的是EF Core的预期行为:
当你用ValueGeneratedOnAdd()配合HasDefaultValueSql("getutcdate()")配置Created属性时,EF的逻辑规则是:
- 如果添加实体时,
Created属性处于未被显式赋值的状态(比如保持CLR默认值DateTime.MinValue),EF会在INSERT语句里省略这个字段,让数据库使用你设置的默认值getutcdate()。 - 但如果你给
Created显式赋了值——哪怕是通过反射修改私有属性(就像你用SetPrivatePropertyValue做的那样),EF会判定这个值是你明确要存入数据库的,所以会把该值包含在INSERT语句中,直接覆盖数据库的默认值。
你的测试代码里已经通过反射把Created改成了1955-09-26,EF检测到这个属性被修改过,自然会优先使用你设置的值,而非忽略它去调用数据库默认值。
强制使用数据库默认值的方法
如果不管代码里有没有给Created赋值,都想让数据库生成默认值,需要把属性配置修改为:
builder.Property(b => b.Created) .HasDefaultValueSql("getutcdate()") .ValueGeneratedOnAdd() .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
这样配置后,EF会始终认定该值由数据库生成,即使你手动赋值,也会在INSERT时忽略该值,让数据库使用默认值。需要注意的是,DatabaseGeneratedOption.Computed会让EF在插入完成后,重新从数据库读取这个值并更新到实体对象上。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

