Entity Framework Core:如何向带默认值的非空列插入Null值?
解决方法
方法1:配置EF Core使用数据库默认值(推荐)
问题核心是EF Core会将实体中CreateDate的null值显式传递给数据库,而数据库列不允许null。要让EF Core在插入时忽略该字段,交由数据库使用默认值填充,需完成以下配置:
调整实体类(可选但更规范)
若不需要在代码中手动设置CreateDate,可将其改为非可空类型,与数据库约束保持一致:public class ItemSoldPrice { public int Id { get; set; } // ... 其他属性 public DateTime CreateDate { get; set; } // 移除可空标记? }在DbContext中配置字段生成规则
在OnModelCreating方法里,为CreateDate绑定数据库默认值并标记为插入时自动生成:protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<ItemSoldPrice>() .Property(p => p.CreateDate) .HasDefaultValueSql("GETDATE()") // 指定数据库默认值函数 .ValueGeneratedOnAdd(); // 标记该字段值在插入时由数据库生成 }配置后,EF Core插入新实体时不会将
CreateDate包含在INSERT语句中,数据库会自动用GETDATE()填充该列。若需保留实体类中CreateDate的可空类型,此配置依然生效——当实体的CreateDate为null时,EF Core会忽略该字段,数据库仍会应用默认值。
方法2:插入前手动赋值
如果需要在部分场景手动控制CreateDate的值,可在添加实体前直接赋值:
var newItem = new ItemSoldPrice { // ... 其他属性赋值 CreateDate = DateTime.Now // 或DateTime.UtcNow,需匹配数据库时区设置 }; dbContext.ItemSoldPrices.Add(newItem); dbContext.SaveChanges();
方法3:重写SaveChanges全局处理
若希望批量处理所有实体的创建时间字段,可重写DbContext的SaveChanges方法,自动为CreateDate为null的新增实体赋值:
public override int SaveChanges() { var addedItems = ChangeTracker .Entries() .Where(e => e.Entity is ItemSoldPrice && e.State == EntityState.Added); foreach (var entry in addedItems) { var item = (ItemSoldPrice)entry.Entity; if (item.CreateDate == null) { item.CreateDate = DateTime.Now; } } return base.SaveChanges(); }
内容的提问来源于stack exchange,提问作者Robin Sun
相关产品推荐
相关产品推荐

