项目环境
- EF Core 6
- Pomelo.EntityFrameworkCore.MySql 6
- MySQL 5.7
背景说明
项目需要,实体中要添加UpdateTime字段,当记录被修改时自动记录修改时间,因此计划采用MySQL的默认时间戳来实现,关于在MySQL中实现自动更新时间可以参考该文章:MySQL设置更新记录时自动更新某字段 – 寒九 (hhao.wang)
根据EF Core的文档,可以使用如下方式添加默认Sql值:
modelBuilder.Entity<Student>() .Property(s=>s.UpdateTime) .HasColumnType("datetime") .HasColumnName("update_time") .HasDefaultValueSql("CURRENT_TIMESTAMP");
若要在值添加或更新时修改该字段则可以使用ValueGeneratedOnAddOrUpdate方法:
modelBuilder.Entity<Student>() .Property(s=>s.UpdateTime) .HasColumnType("datetime") .HasColumnName("update_time") .ValueGeneratedOnAddOrUpdate() .HasDefaultValueSql("CURRENT_TIMESTAMP");
理论上应该生成的DDL语句为:
ALTER TABLE student ADD COLUMN update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
但是按照以上方法进行配置后,发现无法反映到数据库中,生成的DDL语句中并没有ON UPDATE
相关的语句:
ALTER TABLE student ADD COLUMN update_time datetime DEFAULT CURRENT_TIMESTAMP;
问题定位
经过查询Pomelo的仓库Issue,发现Pomelo压根没有支持 ValueGeneratedOnAddOrUpdate
方法,并且该问题也已经有很多人遇到过:
问题解决
既然Pomelo并未支持 ValueGeneratedOnAddOrUpdate
方法,只能采取折中的方法实现,即将默认的sql值从 CURRENT_TIMESTAMP
改为 CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
即可实现:
modelBuilder.Entity<Student>() .Property(s=>s.UpdateTime) .HasColumnType("datetime") .HasColumnName("update_time") .ValueGeneratedOnAddOrUpdate() .HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP");