Dictionary<string,object>存为jsonb后取出变为JToken的技术问题
解决jsonb字段映射Dictionary<string, object>时返回JToken的问题
当你把IDictionary<string, object>类型的Parameters属性以PostgreSQL的jsonb类型存储,从数据库读取时却变成JToken类型,本质是ORM(比如EF Core)默认会将jsonb序列化为JToken以保留JSON原始结构,而非你期望的字典类型。下面是几种解决办法:
1. 配置EF Core类型转换器
如果用EF Core,在DbContext的OnModelCreating方法里给该属性指定转换规则,强制将jsonb转成字典:
使用Newtonsoft.Json的版本
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<ExecuteQueryTask>() .Property(t => t.Parameters) .HasColumnType("jsonb") .HasConversion( dict => JsonConvert.SerializeObject(dict), json => JsonConvert.DeserializeObject<Dictionary<string, object>>(json) ); }
使用System.Text.Json的版本
如果项目用的是System.Text.Json而非Newtonsoft:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<ExecuteQueryTask>() .Property(t => t.Parameters) .HasColumnType("jsonb") .HasConversion( dict => JsonSerializer.Serialize(dict, JsonSerializerOptions.Default), json => JsonSerializer.Deserialize<Dictionary<string, object>>(json, JsonSerializerOptions.Default) ); }
2. 手动转换JToken为字典
如果没法修改EF配置,或者通过其他方式读取数据,可以在拿到数据后手动转换:
// 假设读取到的实体实例为task if (task.Parameters is JToken jToken) { task.Parameters = jToken.ToObject<Dictionary<string, object>>(); }
3. 通过特性指定序列化行为
给Parameters属性加Newtonsoft.Json的特性,指定转换类型:
using Newtonsoft.Json.Converters; public sealed class ExecuteQueryTask { // 其他属性... [JsonProperty(ItemConverterType = typeof(ExpandoObjectConverter))] public IDictionary<string, object> Parameters { get; set; } }
这样ORM在序列化/反序列化时会自动处理成字典类型。
内容的提问来源于stack exchange,提问作者Hardik Dhuri
相关产品推荐
相关产品推荐

