由 Postgres 支持的 EF Core 实体中的计算时间戳
Posted
技术标签:
【中文标题】由 Postgres 支持的 EF Core 实体中的计算时间戳【英文标题】:Computed timestamps in EF Core entity backed by Postgres 【发布时间】:2021-12-21 05:07:46 【问题描述】:我正在为 Postgres v14 使用 EF Core v5 和 Npgsql EF Core 提供程序 v5。
我希望自动设置 CreatedAt
和 UpdatedAt
计算列。它们都是DateTime
类型。
我试过this:
builder
.Property(x => x.CreatedAt)
.IsRequired()
.HasDefaultValueSql("timestamp with time zone");
builder
.Property(x => x.UpdatedAt)
.IsRequired()
.HasComputedColumnSql("timestamp with time zone", stored: true);
但是在创建表时会抛出 (Npgsql.PostgresException (0x80004005): 42601: syntax error at or near ")"
)。
如果我删除上面的代码,那么一切正常,因此问题与该代码无关。
我认为 timestamp with time zone
对 UTC timestamps 是正确的,但整体语法显然是错误的。我该如何解决?
【问题讨论】:
在 github 上交叉发布并在那里回答:github.com/npgsql/efcore.pg/issues/2079 【参考方案1】:timestamp with time zone
是 Postgresql 类型名称而不是值。当前带时区的时间戳的值为current_timestamp
或now()
。试试
.HasDefaultValueSql("now()");
【讨论】:
谢谢!请注意,它会因Npgsql.PostgresException (0x80004005): 42P17: generation expression is not immutable
而失败。我也在尝试使用here 显示的标准sql 语法,而now()
被认为是“非标准的”。但是你确认我的语法完全错误,所以谢谢你。
哦,now()
是 Postgresql 特有的。请。尝试current_timestamp
而不是now()
。它在语义上相同,但 SQL 标准。
这给出了同样的例外......我认为我在某处缺少一些神奇的成分。你是对的,我使用数据类型作为值,你给我的值可能是正确的。但是 EF 提供者期待更多……但不确定是什么。再次感谢。
谁在产生错误,HasComputedColumnSql 还是 HasDefaultValueSql?您当然不能在存储的计算列中使用 volatile 表达式..
你说得对,是HasComputedColumnSql
扔了。但是必须有办法做到这一点,因为例如我可以将HasComputedColumnSql("getutcdate()")
用于SQL Server。【参考方案2】:
使用这个:
.HasDefaultValueSql("CURRENT_TIMESTAMP");
【讨论】:
谢谢。与其他答案相同,不幸的是,在创建数据库时会导致异常。 您不能在 Postgres 的 HasComputedColumnSql 中指定可变语句。如果您希望在 UPDATE 上更新字段,则必须使用触发器。 是的,不幸的是,情况似乎如此。感谢您的确认。以上是关于由 Postgres 支持的 EF Core 实体中的计算时间戳的主要内容,如果未能解决你的问题,请参考以下文章