在 Symfony 2 中订购分页结果

Order pagination result in Symfony 2

我对 Symfony 2.7 中的分页顺序有疑问。

在我们使用分页之前,我们使用 PHP 函数 usort 对一些东西进行排序。但我现在的问题是,我们如何以与 usort 相同的顺序在 doctrine 查询中实现 usort。这需要与分页器一起工作。因为当我们现在使用查询(在下面)时,我们没有得到正确的结果。

usort 函数:

        usort($result, function ($a, $b) {
        $aBegin = $a->getStartDate() ?: $a->getCreatedDate();
        $bBegin = $b->getStartDate() ?: $b->getCreatedDate();
        if ($aBegin < $bBegin) {
            return -1;
        }
        if ($aBegin == $bBegin) {
            return 0;
        }
        if ($aBegin > $bBegin) {
            return 1;
        }

        return 0;
    });

我们如何在以下查询中实现 usort:

    $build = $this->createQueryBuilder('building');
    $build
        ->addSelect('users', 'furniture')
        ->join('building.users', 'users')
        ->leftJoin('building.furniture', 'furniture')
        ->where('building.id = :id')
        ->setParameter('id', $id)
        ->orderBy('building.getStartDate', 'ASC')
        ->addOrderBy('building.getCreatedDate', 'DESC');

    $paginator = new Paginator($build->getQuery(), $fetchJoinCollection = true);
    $result = $paginator->getQuery()
        ->setFirstResult($offset)
        ->setMaxResults($limit)
        ->getResult();

谢谢!

学说 orm:2.2.3, Symfony 版本:2.7

要添加这样的条件,您可以在 select 子句中使用 CASE 表达式。您可以编写类似 CASE WHEN b.startDate IS NULL THEN b.createdDate ELSE b.startDate END 的代码来实现 usort 函数中描述的行为。

也就是说,您不能简单地将其添加到您的 order by 子句中。您需要 select 这个值,给它一个别名,然后根据新的 selected 值添加一个顺序。因为您可能不想获得 mixed result (where your entities would be mixed with scalar values), you can use the HIDDEN 关键字来从结果集中删除计算字段。

全部放在一起,可能是这样的:

// $qb your query builder with all your other parameters
$qb->addSelect('CASE 
    WHEN building.startDate IS NULL 
        THEN building.createdDate 
        ELSE building.startDate
    END 
    AS HIDDEN beginDate');
$qb->orderBy('beginDate', 'DESC');

请注意,虽然这有效,但如果您的 table 中有很多条目,您可能会遇到性能问题,因为整个 table 很可能会被完全扫描,以便此查询成为已执行。