在 OrmLite 中使用 PostgreSQL 聚合函数
Using PostgreSQL aggregate functions with OrmLite
我正在尝试弄清楚如何使用 OrmLite 处理使用聚合函数的查询的查询结果。
例如接受这个查询:
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 values = db.Select<Tuple<Blog, List<BlogToBlogCategory>>>(q);
它生成正确的 SQL:
SELECT b.*, json_agg(btc)
FROM "blog" "b" INNER JOIN "blog_to_blog_category" "btc" ON ("b"."id" = "btc"."blog_id")
GROUP BY "b"."id"
但是解析结果报错:
Column must be between 0 and 19
我不确定如何将查询结果解析为父 table 和子 table 列表。
可能吗?
返回 JSON 函数与 return 返回一个额外的字符串列相同。由于您不能将元组与 Table 类型和标量值混合使用,因此您需要另一种方法来访问其他字符串值。
您可以将自定义结果解析为 dynamic result set,单独访问所有列,但在这种情况下,您可以创建自定义结果 class,其中包含额外的字符串列和 return 键入的结果,例如:
public class BlogResult : Blog
{
public string Json { get; set; }
private List<BlogToBlogCategory> results;
public List<BlogToBlogCategory> Results =>
results ??= Json.FromJson<List<BlogToBlogCategory>>();
}
您可以在哪里 select 进入自定义类型模型:
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 Json");
var values = db.Select<BlogResult>(q);
但是如果您的 PostgreSQL 列名称使用 snake_case 并且您的 C# 类型使用 PascalCase 您将需要使用自定义序列化这允许在不同 属性 样式的外壳之间进行更宽松的映射,例如:
public static class CustomJsonSerializer
{
public static T FromJson<T>(string json)
{
using var scope = JsConfig.With(new Config {
PropertyConvention = PropertyConvention.Lenient });
return json.FromJson<T>();
}
}
public class BlogResult : Blog
{
public string Json { get; set; }
private List<BlogToBlogCategory> results;
public List<BlogToBlogCategory> Results => results ??=
CustomJsonSerializer.FromJson<List<BlogToBlogCategory>>(Json);
}
我正在尝试弄清楚如何使用 OrmLite 处理使用聚合函数的查询的查询结果。
例如接受这个查询:
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 values = db.Select<Tuple<Blog, List<BlogToBlogCategory>>>(q);
它生成正确的 SQL:
SELECT b.*, json_agg(btc)
FROM "blog" "b" INNER JOIN "blog_to_blog_category" "btc" ON ("b"."id" = "btc"."blog_id")
GROUP BY "b"."id"
但是解析结果报错:
Column must be between 0 and 19
我不确定如何将查询结果解析为父 table 和子 table 列表。
可能吗?
返回 JSON 函数与 return 返回一个额外的字符串列相同。由于您不能将元组与 Table 类型和标量值混合使用,因此您需要另一种方法来访问其他字符串值。
您可以将自定义结果解析为 dynamic result set,单独访问所有列,但在这种情况下,您可以创建自定义结果 class,其中包含额外的字符串列和 return 键入的结果,例如:
public class BlogResult : Blog
{
public string Json { get; set; }
private List<BlogToBlogCategory> results;
public List<BlogToBlogCategory> Results =>
results ??= Json.FromJson<List<BlogToBlogCategory>>();
}
您可以在哪里 select 进入自定义类型模型:
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 Json");
var values = db.Select<BlogResult>(q);
但是如果您的 PostgreSQL 列名称使用 snake_case 并且您的 C# 类型使用 PascalCase 您将需要使用自定义序列化这允许在不同 属性 样式的外壳之间进行更宽松的映射,例如:
public static class CustomJsonSerializer
{
public static T FromJson<T>(string json)
{
using var scope = JsConfig.With(new Config {
PropertyConvention = PropertyConvention.Lenient });
return json.FromJson<T>();
}
}
public class BlogResult : Blog
{
public string Json { get; set; }
private List<BlogToBlogCategory> results;
public List<BlogToBlogCategory> Results => results ??=
CustomJsonSerializer.FromJson<List<BlogToBlogCategory>>(Json);
}