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

EF Core对接PostgreSQL JSONB列时Automapper ProjectTo报错如何解决?

报错原因

你自定义了TestInfo类型到PostgreSQL jsonb类型的序列化值转换器,EF Core无法解析AutoMapper生成的访问Info内部属性(Tags/Counts/InfoName)的表达式,会尝试直接将数据库返回的jsonb字符串强制转换为对应数组/字符串类型,因此抛出类型转换异常。你贴的手动Select可以正常运行是因为你没有映射数组类型的字段,如果手动在Select中增加Tags = s.Info.Tags配置,也会出现同类报错。

最优解决方案(支持投影查询)

使用Npgsql官方提供的JSON序列化映射支持,替换自定义值转换器,EF Core即可正确识别jsonb字段内部属性的访问表达式,自动翻译成PostgreSQL原生jsonb查询语法,适配AutoMapper的ProjectTo逻辑。
步骤如下:

  1. 安装对应NuGet包:
    • 如果你习惯用Newtonsoft.Json:安装Npgsql.EntityFrameworkCore.PostgreSQL.NewtonsoftJson,版本和你当前使用的Npgsql EF Core驱动版本保持一致
    • 如果你习惯用System.Text.Json:安装Npgsql.EntityFrameworkCore.PostgreSQL.Json,版本和驱动保持一致
  2. 修改DbContext注册配置,开启JSON序列化支持:
    services.AddDbContext<你的DbContext类名>(opt => 
        opt.UseNpgsql("你的数据库连接字符串", o => 
        {
            // 用Newtonsoft.Json就选这个
            o.UseNewtonsoftJson();
            // 用System.Text.Json就选这个
            // o.UseJson();
        })
    );
    
  3. 删除TestConfig中自定义的HasConversion配置,修改后配置如下:
    public override void Configure(EntityTypeBuilder<Test> builder)
    {
        builder.HasKey(m => m.Id);
        builder.Property(s => s.Info)
            .HasColumnType("jsonb");
        builder.HasIndex(s => s.Info)
            .HasMethod("gin")
            .HasOperators("jsonb_ops");
    }
    

修改完成后你的原有ProjectTo代码就可以正常运行了。

临时兼容方案

如果你不想修改现有值转换器,可以先将符合条件的实体加载到内存后再执行映射,缺点是会加载Test实体的全部字段,性能略低于投影查询:

[HttpGet]
[Route("/test/{id}")]
public async Task<IActionResult> GetTest([FromRoute (Name = "id")][Required]string id)
{ 
   var entities = await _context.Tests.Where(s => s.Id == id).ToListAsync();
   var dtoList = _mapper.Map<List<TestDTO>>(entities);
   return Ok(dtoList); 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 06:24:05