You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过LinqToDB向PostgreSQL的timestamp without time zone字段写入DateTime?

解决LinqToDB向PostgreSQL的timestamp without time zone字段写入DateTime的问题

问题场景

环境:C# + Linq2db + Postgres
表实体定义:

[Table("my_table", Schema = "myScheme")]
public class TableEntity 
{
    // 其他字段...
    [Column("dt", DbType = "timestamp without time zone", DataType = DataType.DateTime)]
    public DateTime DT { get; set; }
    // 其他字段...
}

设置实体值时指定了Local时区:

tableEntity.DT = DateTime.SpecifyKind(someDate, DateTimeKind.Local);

执行插入命令时:

await dataConn.InsertWithInt32IdentityAsync(tableEntity);

LinqToDB会自动将DateTimeKind.Local的时间转为UTC,导致PostgreSQL抛出异常:

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.

要求必须使用timestamp without time zone字段,需解决写入问题。

解决方案

1. 直接将DateTime转为Unspecified时区

PostgreSQL的timestamp without time zone不存储时区信息,因此只需将DateTime的Kind设为Unspecified,LinqToDB就不会触发自动时区转换:

// 方法1:直接指定Kind为Unspecified
tableEntity.DT = DateTime.SpecifyKind(someDate, DateTimeKind.Unspecified);

// 方法2:基于原时间的Ticks创建新的Unspecified时间(适合Local转Unspecified)
tableEntity.DT = new DateTime(someDate.Ticks, DateTimeKind.Unspecified);

2. 配置LinqToDB禁用自动时区转换

通过LinqToDB的PostgreSQL配置选项,全局禁用timestamp without time zone字段的Local到UTC自动转换:

var dataConn = new DataConnection(PostgreSQLTools.GetDataProvider(), connectionString);
dataConn.AddMappingSchemaConfiguration(config =>
{
    config.SetPostgreSQLOptions(options =>
    {
        // 关闭timestamp without time zone字段的自动时区转换
        options.TimestampWithoutTimeZoneConversion = TimestampWithoutTimeZoneConversionMode.None;
    });
});

注:该配置需对应LinqToDB 3.0+版本,不同版本配置方式可能略有差异。

3. 为字段添加自定义类型转换器

在实体字段上绑定自定义转换器,强制将传入的DateTime转为Unspecified后再写入数据库:

// 自定义转换器
public class UnspecifiedDateTimeConverter : ValueConverter<DateTime, DateTime>
{
    public UnspecifiedDateTimeConverter() : base(
        // 写入数据库前转为Unspecified
        input => DateTime.SpecifyKind(input, DateTimeKind.Unspecified),
        // 读取时保持原样
        output => output)
    {
    }
}

// 在实体字段上指定转换器
[Column("dt", DbType = "timestamp without time zone", DataType = DataType.DateTime, ConverterType = typeof(UnspecifiedDateTimeConverter))]
public DateTime DT { get; set; }

内容的提问来源于stack exchange,提问作者VladimirK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 10:42:54