Npgsql EF 6:尽管基础列具有 timestampTz 类型,但插入 UTC 日期时间值失败

Npgsql EF 6: inserting a UTC date time value fails although the underlying column has a timestampTz type

我最近将我的应用更新为:Vs 2019、EntityFramework.6.4.4、EntityFramework6.Npgsql.6.4.3 和 Npgsql.6.0.4

之前,一切正常。更新后,我测试了插入和读取数据库(postgreSql V13)的不同用例。

在插入一个带有 timestampTz 值的简单实体时,出现以下异常:

Cannot write DateTime with Kind=UTC to PostgreSQL type 'timestamp without time zone', consider using 'timestamp with time zone'. Note that it's not possible to mix DateTimes with different Kinds in an array/range. See the Npgsql.EnableLegacyTimestampBehavior AppContext switch to enable legacy behavior.

这是我使用的代码片段。 实体 class (POCO):

    [DataContract]
    [Table("TSHH_ShiftHistory", Schema = "ppc")]
    public class TSHH_ShiftHistory
    {
        [DataMember]
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int SHH_RecordingOrder { get; set; }
        //..
        [DataMember]
        public DateTime? SHH_Started_UTC { get; set; }
        [DataMember]
        public DateTime? SHH_Finished_UTC { get; set; }
        // .. 
    }

并写入数据库:

    shiftHistory = new TSHH_ShiftHistory();
    shiftHistory.SHH_Started_UTC = dateTimeStarted; // in UTC format
    shiftHistory.SHH_Finished_UTC = dateTimeFinished; // in UTC format

    db.TSHH_ShiftHistory.Add(shiftHistory);

    int sc = db.SaveChanges();

以下是我试图获得帮助的网站:

https://www.npgsql.org/doc/release-notes/6.0.html#timestamp-rationalization-and-improvements https://www.npgsql.org/doc/types/datetime.html#timestamps-and-timezones https://www.npgsql.org/doc/api/NpgsqlTypes.NpgsqlDbType.html

https://github.com/npgsql/npgsql/issues/2669 https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions?tabs=data-annotations#the-valueconverter-class

解决方法:

AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);

当然,我在文章中读到了它,但是当我想要自 npgsql 6.0 以来关于时间戳和时区映射的新行为时,我没有看到需要反驳。但它来了。我尝试将开关设置为 truefalse。令人惊讶的是,无论设置值如何,都没有引发异常。

至少我取消了“AppContext.SetSwitch(..);”这一行的注释并且在插入 UTC 日期时间值时再次引发异常。

我的嫌疑人:我想知道,如果缺少“AppContext.SetSwitch(..);”声明是一个未初始化的行为并导致不可预测的结果。

如果有人能证实我的怀疑,我会很高兴,也许是@Shay Rojansky?

您使用的是旧的 (non-core) EF6,很可能还需要对其进行调整以适应新的时间戳行为(EF Core 提供程序肯定会这样做)。不幸的是,这不会发生,因为不再开发 EF6。

我通常建议不要使用更新版本的 Npgsql 运行 EF6;这些组合没有经过测试,可能会以各种方式失败。随着 EF6 被有效冻结,我建议也保留相同版本的 Npgsql。