【问题标题】:Getting AutoQuery pagination to work with left join让 AutoQuery 分页与左连接一起工作
【发布时间】:2019-07-04 01:56:50
【问题描述】:

在我的 AutoQuery 请求中,我指定了一个左连接,因此我可以查询连接表中的属性。

public class ProductSearchRequest : QueryDb<Book>
    , ILeftJoin<Book, BookAuthor>, ILeftJoin<BookAuthor, Author>
{}

如果我像这样使用标准的自动查询方式:

var q = AutoQuery.CreateQuery(request, base.Request);
var results = AutoQuery.Execute(request, q);

请求了 100 个,然后通常会重新调整不到 100 个,因为 Take() 是基于左连接的结果。

为了解决这个问题,我正在这样做:

var q = AutoQuery.CreateQuery(request, base.Request);
q.OrderByExpression = null //throws error if orderby exists
var total = Db.Scalar<int>(q.Select(x => Sql.CountDistinct(x.Id))); //returns 0

var q1 = AutoQuery.CreateQuery(request, base.Request).GroupBy(x => x);

var results = Db.Select<Book>(q1);

return new QueryResponse<Book>
{
    Offset = q1.Offset.GetValueOrDefault(0),
    Total = total
    Results = results
};

group by 似乎返回正确数量的结果,因此分页有效,但 Total 返回 0。

我也试过了:

var total2 = (int)Db.Count(q1);

但即使q1GroupBy(),它也会返回包括左连接在内的结果数,而不是实际查询

我怎样才能得到查询的真实总数?

(获取一些关于如何使用自动查询和左连接进行分页和总计的官方文档将非常有帮助,因为现在它有点令人困惑)

【问题讨论】:

    标签: servicestack


    【解决方案1】:

    您的主要问题源于尝试返回与实际查询 AutoQuery 执行不同的总数。如果您有多个左连接,则总数是它执行的查询的总结果,而不是源表中的行数。

    因此,您不是在寻找“真实总数”,而是在寻找执行不同的查询以获得与执行的查询不同的总数,但仍以原始查询为基础。首先考虑使用普通的 INNER JOINS (IJoin&lt;&gt;) 而不是 LEFT JOINS,因此它只返回连接表中相关行的结果,总数将相应反映。

    您返回0 的总查询可能没有返回任何结果,因此我会查看SQL Profiler 中的查询,以便您可以看到已执行的查询。您还可以启用 Debug 日志记录并在您的 AppHost 中启用 OrmLite 查询的日志记录:

    OrmLiteUtils.PrintSql();
    

    另请注意,整个表的GroupBy() 是不寻常的,您通常会按单个或多个显式选择的列进行分组,例如:

    .GroupBy(x => x.Id);
    .GroupBy(x => new { x.Id, x.Name });
    

    【讨论】:

    • 如果我使用内连接,那么我会丢失一半的数据集,因为不是每个左表在右表中都有一个条目。除非我列出每个属性并且表有很多属性,否则 group by 会引发错误。如果我按 x 分组,那么它似乎为我列出了所有属性。 groupby 返回正确数量的结果,但由于 groupby 原因,它返回多行,因此 count 语句没有正确计算它。我需要将 group by 语句作为子查询以获得正确的计数,但在文档中看不到如何执行此操作。它非常令人沮丧
    • @Guerrilla 你知道在 GROUP BY 中包含聚合 COUNT(...) 的行为是什么吗?这可能不是你想要/想的。如果您只想要查询的行数,您可能需要调用db.RowCount(q),否则我将从您想要首先实际执行的实际 SQL 查询开始,然后看看如何在 OrmLite 中查询它 - 总数将是所有 COUNT(...) 列的总和,因此请确保返回您想要的总数。
    • (int)Db.RowCount(q1.ClearLimits()) 似乎对计数有用,谢谢。我认为您对 groupby 的看法是正确的,我需要手动列出每个属性
    • @Guerrilla 使用左连接分页查询需要不同的策略,例如通过维护引用并查询last key the query was ordered by 或在左连接之前执行pagination within a sub query
    • 对页面进行子选择然后将表连接到子选择的问题是,您只能通过连接的表列查询一页而不是整个数据集。 db.RowCount() 使总计工作。我将调查为什么我不能只按 ID 分组。感谢您的帮助。它现在正在工作,但我不确定我是否做得对。我认为一些带有自动查询连接的分页官方文档会有所帮助,因为它是一项常见任务,并且在文档中没有提到。
    猜你喜欢
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    相关资源
    最近更新 更多