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
相关产品推荐
相关产品推荐

