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

Code First模式下如何设置默认值解决EF Core查询jsonb列的反序列化错误

错误根因

  • 实体类属性初始化语法错误,初始化逻辑未生效,集合属性默认仍为null
  • 实体类字符串属性未设置默认值/可空标注,System.Text.Json默认不支持将JSON中的null值转换为非可空string类型
  • 实体类名定义错误:Employee中Sections属性类型为List<Section>,但你定义的对应类名为Sections(多了后缀s),类型不匹配导致反序列化失败
  • 查询语句语法错误:C#相等判断用双等号==,你写的Where(i.Name === name)多了一个等号

修复步骤

1. 修正实体类定义,正确初始化属性

using System.Text.Json.Serialization;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;

public class Employee
{
    public string Name { get; set; } = string.Empty;

    [Column(TypeName = "jsonb")]
    public List<Section> Sections { get; set; } = new List<Section>();
}

// 修正类名,去掉多余的s,和属性类型保持一致
public class Section
{
    public string Booking { get; set; } = string.Empty;

    [Column(TypeName = "jsonb")]
    public List<Interest> Interests { get; set; } = new List<Interest>();
}

public class Interest
{
    public string Title { get; set; } = string.Empty;
    public List<Meta> Meta { get; set; } = new List<Meta>();
    public List<WithAlt> Images { get; set; } = new List<WithAlt>();
}

public class Meta
{
    public string Type { get; set; } = string.Empty;
    // 直接设置默认空串,避免JSON null转换报错
    public string Content { get; set; } = string.Empty;
}

public class WithAlt
{
    // 匹配JSON中的小写键名
    [JsonPropertyName("content")]
    public string Content { get; set; } = string.Empty;

    [JsonPropertyName("alt")]
    public string Alt { get; set; } = string.Empty;
}

2. 在DbContext中配置JSON序列化规则

在你的catalogDbContext的OnModelCreating方法中添加以下配置,处理反序列化时的null值:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var jsonSerializeOptions = new JsonSerializerOptions
    {
        PropertyNameCaseInsensitive = true,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
        NumberHandling = JsonNumberHandling.AllowReadingFromString
    };

    // 配置Employee的Sections字段序列化规则
    modelBuilder.Entity<Employee>()
        .Property(e => e.Sections)
        .HasConversion(
            v => JsonSerializer.Serialize(v, jsonSerializeOptions),
            v => JsonSerializer.Deserialize<List<Section>>(v, jsonSerializeOptions) ?? new List<Section>()
        );

    // 配置Section的Interests字段序列化规则
    modelBuilder.Entity<Section>()
        .Property(s => s.Interests)
        .HasConversion(
            v => JsonSerializer.Serialize(v, jsonSerializeOptions),
            v => JsonSerializer.Deserialize<List<Interest>>(v, jsonSerializeOptions) ?? new List<Interest>()
        );
}

3. 修正查询语句语法

public async Task<Employee> CheckEmployee(string name)
{
    // 修正相等判断符号,补充lambda参数
    var query = await catalogDbContext.Employee
                .Where(i => i.Name == name)
                .FirstOrDefaultAsync();
    return query;
}

4. 可选:批量处理历史空数据

如果数据库中已经存在为null的jsonb字段,执行SQL批量更新为默认空数组:

UPDATE "Employee" SET "Sections" = '[]'::jsonb WHERE "Sections" IS NULL;

以上配置完成后,新增数据会自动使用属性默认值,历史数据反序列化时遇到null值也会自动转换为默认空集合/空字符串,不会再抛出转换错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:54:01