197 字
1 分钟
EFCore PostgreSql DateTimeOffset报错解决方案

在EFCore的PostgreSql中使用DateTimeOffset可能会报错:

---> System.ArgumentException: Cannot write DateTimeOffset with Offset=08:00:00 to PostgreSQL type 'timestamp with time zone', only offset 0 (UTC) is supported. (Parameter 'value')

Npgsql 支持将 DateTimeOffset 读取和写入具有时区的时间戳,但仅限于 Offset=0

官方文档说明: https://www.npgsql.org/doc/types/datetime.html#timestamps-and-timezones

解决方案1#

在 Main 方法中加上 AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);

解决方案2#

使用转换器

public class DateTimeOffsetUtcConverter : ValueConverter<DateTimeOffset, DateTimeOffset> { public static ValueConverterInfo Instance { get; } = new ValueConverterInfo(typeof(DateTimeOffset), typeof(DateTimeOffset), (i) => new DateTimeOffsetUtcConverter(i.MappingHints)); public DateTimeOffsetUtcConverter() : this(null) { } public DateTimeOffsetUtcConverter(ConverterMappingHints? mappingHints) : base((v) => ToUtc(v), (v) => ToLocal(v), mappingHints) { } public static DateTimeOffset ToLocal(DateTimeOffset v) => v.ToLocalTime(); public static DateTimeOffset ToUtc(DateTimeOffset v) => v.ToUniversalTime(); }

然后在 DbContext 中:

public class MyDbContext { protected override void OnModelCreating(ModelBuilder modelBuilder) { if (provider.Contains("postgresql", StringComparison.OrdinalIgnoreCase)) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var properties = entityType.ClrType.GetProperties() .Where(p => p.PropertyType == typeof(DateTimeOffset) || p.PropertyType == typeof(DateTimeOffset?)); foreach (var property in properties) { modelBuilder .Entity(entityType.Name) .Property(property.Name) .HasConversion(new DateTimeOffsetUtcConverter()); } } } } }
EFCore PostgreSql DateTimeOffset报错解决方案
https://fuwari.vercel.app/posts/efcore-postgresql-datetimeoffset/
作者
ilyfairy
发布于
2024-11-18
许可协议
CC BY-NC-SA 4.0