Недавно я обновил свое приложение до: 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.
Вот фрагменты кода, которые я использую. Класс сущности (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-improvementshttps://www.npgsql.org/doc/types/datetime.html#timestamps-and-timezoneshttps://www.npgsql.org/doc/api/NpgsqlTypes.NpgsqlDbType.html
Npgsql EF 6: сбой временной метки при использовании ExecuteSqlInterpolatedAsynchttps://github.com/npgsql/npgsql/issues/2669https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions?tabs=data-annotations#the-valueconverter-class
Решение:
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
Конечно, я читал об этом в статьях, но я не видел необходимости возвращаться назад, когда мне нужно новое поведение в отношении метки времени с отображением часового пояса, начиная с npgsql 6.0. Но вот оно. Я экспериментировал с установкой переключателя на истинный и ЛОЖЬ. Удивительно, но исключение не возникло независимо от установленного значения.
По крайней мере, я раскомментировал строку "AppContext.SetSwitch(..);" и исключение возникло снова при вставке значения UTC DateTime.
мой подозреваемый: Интересно, если отсутствующий "AppContext.SetSwitch(..);" оператор не является инициализированным поведением и приводит к непредсказуемому результату.
Я был бы рад, если бы кто-нибудь мог подтвердить мои подозрения, может быть, @Shay Rojansky?
Вы используете старый (неосновной) EF6, который, скорее всего, также придется настроить, чтобы учесть новое поведение метки времени (определенно это сделал поставщик EF Core). К сожалению, этого не произойдет, поскольку EF6 больше не разрабатывается.
В целом я бы рекомендовал не запускать EF6 с более новыми версиями Npgsql; эти комбинации не проверяются и могут дать сбой по разным причинам. Поскольку EF6 эффективно заморожен, я бы рекомендовал сохранить ту же версию Npgsql.
Спасибо за Ваш быстрый ответ. Я думаю, что я пойду по пути перехода на EF Core, чтобы избежать возможных проблем в будущем.