.NET6和DateTime问题。无法将Kind=UTC的DateTime写入到PostgreSQL类型为'timestamp without time zone'中。

83

我有一个常见的问题。

无法将带有Kind=UTC的DateTime写入到PostgreSQL类型为'timestamp without time zone'中

我想启用遗留时间戳行为,如此文档所述: https://github.com/npgsql/doc/blob/main/conceptual/Npgsql/types/datetime.md/

public MyDbContext(DbContextOptions<MyDbContext> contextOptions) : base(contextOptions)
        {
            AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
            AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
        }

但是不起作用。我仍然得到同样的错误。

我做错了什么?为什么旧行为不起作用?


你需要分享一些代码来展示你正在做什么,以及包含堆栈跟踪的完整异常信息。 - Shay Rojansky
2
重大更改 https://github.com/npgsql/efcore.pg/issues/2000 - Nick Kovalsky
1
@NickKovalsky,“重大变更”提到“'无法将Kind = Unspecified的DateTime写入PostgreSQL类型'timestamp with time zone'”,这是有道理的,而当前的错误则提到了Kind = UTC。在我看来,这个问题中提到的错误消息非常令人困惑,因为它暗示日期已经是Kind.UTC。当我使用Kind.UTC传递SaveChanges时,我也遇到了这个错误,这是没有意义的(我希望它能够将UTC日期持久化到没有时区的时间戳中)。 - Alexei - check Codidact
我觉得有必要对“为什么”以这种方式实现这种行为进行评论 - 这是因为Postgresql实际上甚至不在“带时区的时间戳”类型中存储时区 - 它只是假设输入时间是在UTC中。所以在这个问题上“开枪打脚”真的很容易,尤其是当你使用类似DateTime.Now这样的东西时。关于这个问题的更多信息可以在这里找到 - https://stackoverflow.com/questions/5876218/difference-between-timestamps-with-without-time-zone-in-postgresql - undefined
14个回答

2

对于我来说,我已经使用dotnet ef migrations add更新了项目。

命令参考:

dotnet ef migrations add <MigrationName> --context <YoutContextClassName> --startup-project <../Path to your startup proyect> --verbose

在创建迁移文件后,PostgreSQL将所有带有时区的datetime更改为不带时区的datetime。

希望这对您有用。

注意:

  • 我已从net5.0升级到net6.0
  • postgresql 6.0.X
  • 使用代码优先于数据库。

更新:

此外,您需要检查DateTime的Kind是否为Utc,如果不是,则可以使用DateTime的静态SpecifyKind方法强制设置为Utc。

enter image description here

祝好!


1

当我的控制器反序列化对象并尝试使用EF和Npgsql.EntityFrameworkCore.PostgreSQL进行插入/更新时,我遇到了相同的问题。我对所有日期使用了ToUniversalTime(),这对我很有效。


0
我知道我晚了,但这是我通常处理这种情况的方式:
DateTime.SpecifyKind((DateTime)MyNullableDateTimeField!, DateTimeKind.Utc)

2
感谢您对Stack Overflow社区做出贡献的兴趣。这个问题已经有很多答案了,其中一个答案已经得到社区广泛验证。您确定您的方法之前没有被提到过吗?如果是这样的话,能否解释一下您的方法与众不同的地方,在什么情况下您的方法可能更好,并且为什么您认为之前的答案不够满意。您可以编辑您的回答并提供解释吗? - Jeremy Caney

-2
我找到了答案。不要将这些行添加到您的dB上下文中。而是在WFP应用程序中按照以下方式添加到MainWindow.xaml.cs:

在public MainWindow方法中,在InitializeComponent语句之前添加"EnableLegacyTimestampBehavior"行。

您不需要"DisableDateTimeInfinityConversions"语句。

现在,您的带有DateTime的代码将正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接