让 AutoQuery 分页与左连接一起使用

Getting AutoQuery pagination to work with left join

在我的 AutoQuery 请求中,我指定了一个左连接,这样我就可以查询连接中的属性 table。

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
};

分组似乎 return 正确的结果数,因此分页有效,但 Total returns 0.

我也试过:

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

但是即使 q1 有一个 GroupBy() 它 return 的结果数量包括左连接而不是实际查询

如何获得查询的真实总数?

(获得一些关于如何使用自动查询和左连接进行分页和总计的官方文档会非常有帮助,因为现在有点混乱)

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

所以您不是在寻找 "True total",而是希望执行不同的查询以获得与已执行的查询不同的总计,但仍以原始查询为基础.首先考虑使用普通的 INNER JOINS (IJoin<>) 而不是 LEFT JOINS,因此只有 returns 连接 tables 中相关行的结果,总数将相应地反映出来。

你的 returns 0 的总查询可能 return 没有结果,所以我会在 SQL Profiler 中查看查询所以你可以看到执行的查询。您还可以启用 Debug 日志记录并在您的 AppHost 中启用 OrmLite 查询日志记录:

OrmLiteUtils.PrintSql();

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

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