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

在OrmLite中使用PostgreSQL聚合函数的结果映射问题

你遇到的错误是因为OrmLite的泛型Tuple映射逻辑要求返回的数据库列和Tuple泛型参数的可映射字段一一对应,而json_agg返回的是单个JSON字符串列,无法直接映射为List<BlogToBlogCategory>集合类型,导致列匹配逻辑异常抛出错误。

以下是3种可行的实现方案:


方案1:自定义DTO接收+手动反序列化JSON

首先定义接收结果的DTO类:

public class BlogWithCategories : Blog
{
    // 接收json_agg返回的JSON字符串
    public string CategoriesJson { get; set; }
    
    // 忽略OrmLite映射,直接反序列化得到子集合
    [Ignore]
    public List<BlogToBlogCategory> Categories => 
        System.Text.Json.JsonSerializer.Deserialize<List<BlogToBlogCategory>>(CategoriesJson);
}

修改查询语句,给聚合字段加别名匹配DTO属性:

var q = db
    .From<Blog>(db.TableAlias("b"))
    .Join<BlogToBlogCategory>((b,btc) => b.Id == btc.BlogId, db.TableAlias("btc"))
    .GroupBy(x => x.Id)
    .Select("b.*, json_agg(btc) AS CategoriesJson");
    
var values = db.Select<BlogWithCategories>(q);
// 直接访问每个元素的Categories属性即可得到子表集合

方案2:不定义DTO,用动态类型中转

如果不想新增DTO类,可以用动态类型接收查询结果后手动转换:

var q = db
    .From<Blog>(db.TableAlias("b"))
    .Join<BlogToBlogCategory>((b,btc) => b.Id == btc.BlogId, db.TableAlias("btc"))
    .GroupBy(x => x.Id)
    .Select("b.*, json_agg(btc)");

var rawResults = db.Select<dynamic>(q);
var values = rawResults.Select(r => new Tuple<Blog, List<BlogToBlogCategory>>(
    r.ConvertTo<Blog>(),
    System.Text.Json.JsonSerializer.Deserialize<List<BlogToBlogCategory>>(r.json_agg.ToString())
)).ToList();

方案3:使用OrmLite原生关联查询API(无需手动写聚合SQL)

如果你的需求只是查询Blog实体和关联的BlogToBlogCategory集合,可以直接用OrmLite自带的LoadSelectAPI,不需要手动写分组和JSON聚合逻辑:

  1. 首先在Blog实体类中添加关联属性标记:
public class Blog
{
    public int Id { get; set; }
    // 其他原有属性...
    
    // 标记为关联引用属性
    [Reference]
    public List<BlogToBlogCategory> Categories { get; set; }
}
  1. 直接调用LoadSelect查询:
// OrmLite会自动执行关联查询并组装父子结构
var values = db.LoadSelect<Blog>();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 17:45:09