EF Core使用Pomelo时ValueGeneratedOnAddOrUpdate不起作用

项目环境

  • 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 方法,并且该问题也已经有很多人遇到过:

Migration: ValueGeneratedOnUpdate · Issue #687 · PomeloFoundation/Pomelo.EntityFrameworkCore.MySql (github.com)

问题解决

既然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");

留下评论

您的电子邮箱地址不会被公开。

Captcha Code