Ядро .net postgres EF Невозможно записать DateTime с Kind = Local в тип PostgreSQL «метка времени с часовым поясом»C#

Место общения программистов C#
Ответить
Anonymous
 Ядро .net postgres EF Невозможно записать DateTime с Kind = Local в тип PostgreSQL «метка времени с часовым поясом»

Сообщение Anonymous »

У меня есть консольное приложение .Net6, использующее пакеты nuget:
  • "Microsoft.EntityFrameworkCore, версия 6.0.8"
  • "Npgsql.EntityFrameworkCore.PostgreSQL, версия 6.0.6"
  • "Npgsql, версия 6.0.6"
Я использую postgres 14.4, поскольку он установлен и используется для запуска сценариев и т. д.

Я запускаю сценарий .sql под названием «createTables.sql», который выглядит следующим образом

Код: Выделить всё

create table if not exists "Messages" (
"Id" uuid primary key,
"Time" timestamp without time zone,
"MessageType" text,
"Message" text
);
Мой основной контекст EF выглядит так

Код: Выделить всё

namespace Database;

public class MessageContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var dbConfig = Configurer.Config.MessageDbConfig;
optionsBuilder.UseNpgsql(new NpgsqlConnectionStringBuilder
{
Database = dbConfig.DbName,
Username = dbConfig.Username,
Password = dbConfig.Password,
Host = dbConfig.Host,
Port = dbConfig.Port,
Pooling = dbConfig.Pooling
}.ConnectionString,
optionsBuilder => optionsBuilder.SetPostgresVersion(Version.Parse("14.4")));

base.OnConfiguring(optionsBuilder);
}

public DbSet Messages { get; set; }
}

public class Msg
{
public Guid Id { get; set; } = Guid.NewGuid();
public DateTime Time { get; set; } = DateTime.Now;
public string MessageType { get; set; }
public string Message { get; set; }
}

после запуска файла .sql с помощью команды psql из командной строки. Я проверяю pgAdmin 4 и вижу
Изображение

, подтверждающее, что тип столбца временная метка без часового пояса. Однако когда я создаю новое сообщение через

Код: Выделить всё

    using var context = new MessageContext();
context.Messages.Add(new Msg
{
MessageType = message.GetType()
.FullName,
Message = message.ToString()
});
context.SaveChanges();

при сохранении изменений получаю исключение

Код: Выделить всё

Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
---> System.InvalidCastException: Cannot write DateTime with Kind=Local to PostgreSQL type 'timestamp with time zone', only UTC is supported. 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.
at Npgsql.Internal.TypeHandlers.DateTimeHandlers.TimestampTzHandler.ValidateAndGetLength(DateTime value, NpgsqlParameter parameter)
at Npgsql.Internal.TypeHandlers.DateTimeHandlers.TimestampTzHandler.ValidateObjectAndGetLength(Object value, NpgsqlLengthCache& lengthCache, NpgsqlParameter parameter)
at Npgsql.NpgsqlParameter.ValidateAndGetLength()
at Npgsql.NpgsqlParameterCollection.ValidateAndBind(ConnectorTypeMapper typeMapper)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(StateManager stateManager, Boolean acceptAllChangesOnSuccess)
at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
Выглядит очень противоречиво, поскольку он установлен без часового пояса, а при создании сообщения создается экземпляр свойства «Время» с типом местного часового пояса. Если я переключу его на «DateTime.UtcNow» вместо «DateTime.Now», это сработает. Я не понимаю, почему он выдает исключение, когда я устанавливаю «временную метку без часового пояса». очевидно, что простое решение — просто использовать время в формате UTC, но, тем не менее, почему выдается исключение, зная подробности?

Подробнее здесь: https://stackoverflow.com/questions/736 ... resql-type
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»