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 以来关于时间戳和时区映射的新行为时,我没有看到需要反驳。但它来了。我尝试将开关设置为 true 和 false。令人惊讶的是,无论设置值如何,都没有引发异常。
至少我取消了“AppContext.SetSwitch(..);”这一行的注释并且在插入 UTC 日期时间值时再次引发异常。
我的嫌疑人:我想知道,如果缺少“AppContext.SetSwitch(..);”声明是一个未初始化的行为并导致不可预测的结果。
如果有人能证实我的怀疑,我会很高兴,也许是@Shay Rojansky?
您使用的是旧的 (non-core) EF6,很可能还需要对其进行调整以适应新的时间戳行为(EF Core 提供程序肯定会这样做)。不幸的是,这不会发生,因为不再开发 EF6。
我通常建议不要使用更新版本的 Npgsql 运行 EF6;这些组合没有经过测试,可能会以各种方式失败。随着 EF6 被有效冻结,我建议也保留相同版本的 Npgsql。
我最近将我的应用更新为: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
解决方法:
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
当然,我在文章中读到了它,但是当我想要自 npgsql 6.0 以来关于时间戳和时区映射的新行为时,我没有看到需要反驳。但它来了。我尝试将开关设置为 true 和 false。令人惊讶的是,无论设置值如何,都没有引发异常。
至少我取消了“AppContext.SetSwitch(..);”这一行的注释并且在插入 UTC 日期时间值时再次引发异常。
我的嫌疑人:我想知道,如果缺少“AppContext.SetSwitch(..);”声明是一个未初始化的行为并导致不可预测的结果。
如果有人能证实我的怀疑,我会很高兴,也许是@Shay Rojansky?
您使用的是旧的 (non-core) EF6,很可能还需要对其进行调整以适应新的时间戳行为(EF Core 提供程序肯定会这样做)。不幸的是,这不会发生,因为不再开发 EF6。
我通常建议不要使用更新版本的 Npgsql 运行 EF6;这些组合没有经过测试,可能会以各种方式失败。随着 EF6 被有效冻结,我建议也保留相同版本的 Npgsql。