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

如何为Npgsql + EF Core配置JSON序列化选项

在EF Core中处理PostgreSQL JSONB列的NaN数据

问题描述

我在PostgreSQL表的JSONB列中存储了包含“NaN”的数据,使用EF Core读取该数据时会抛出异常。已知System.Text.Json可通过以下配置允许解析NaN:

var options = new JsonSerializerOptions
{
    NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals
};

但不知道如何在通过UseNpgsql()配置DbContext时全局添加这个选项。目前已通过为特定属性创建ValueConverter并使用HasConversion注册解决,但这种方式过于冗余,希望了解全局实现方案。

全局解决方案

方式1:直接配置Npgsql的JSON序列化选项

在注册DbContext时,通过UseNpgsql的扩展方法UseJsonOptions全局设置System.Text.Json的配置:

// Program.cs 或 Startup.cs 的服务注册代码
builder.Services.AddDbContext<YourDbContext>(options =>
    options.UseNpgsql("你的连接字符串", npgsqlOptions =>
        npgsqlOptions.UseJsonOptions(jsonOptions =>
            jsonOptions.SerializerOptions.NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals)));

或者在DbContext的OnConfiguring方法中配置:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseNpgsql("你的连接字符串", npgsqlOptions =>
        npgsqlOptions.UseJsonOptions(jsonOptions =>
            jsonOptions.SerializerOptions.NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals));
}

此配置会自动应用到所有使用System.Text.Json处理的JSONB列,无需为每个属性单独配置转换器。

方式2:复用全局JsonSerializerOptions实例

如果需要统一管理更多JSON序列化规则,可以先定义全局的JsonSerializerOptions实例,再传入Npgsql配置:

// 定义全局JSON配置
var globalJsonOpts = new JsonSerializerOptions
{
    NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

// 注册DbContext时关联全局配置
builder.Services.AddDbContext<YourDbContext>(options =>
    options.UseNpgsql("你的连接字符串", npgsqlOptions =>
        npgsqlOptions.UseJsonOptions(jsonOptions =>
            jsonOptions.SerializerOptions = globalJsonOpts)));

补充:属性级转换器方案(灵活但冗余)

如果仅需针对特定属性处理,之前的HasConversion方式依然可用,示例代码如下:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<YourEntity>()
        .Property(e => e.TargetJsonbProperty)
        .HasConversion(
            value => JsonSerializer.Serialize(value, null),
            json => JsonSerializer.Deserialize<YourJsonDataType>(json, new JsonSerializerOptions
            {
                NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals
            }));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 07:02:49