Trong trường hợp của bạn, không phải pagerfanta thực hiện truy vấn phụ. Đó là nguồn trình tạo trình tạo truy vấn của bạn mà nó đến từ đó.
Tôi thường có chức năng trong kho lưu trữ thực thể trả về phiên bản trình tạo truy vấn đơn giản thay vì kết quả. Bạn còn viết một trình xây dựng truy vấn hiệu quả. Sau đó, tôi cung cấp trình tạo truy vấn đó vào DoctrineORMAdapter.
Tôi đã có chức năng này helper mà tôi sử dụng trong suốt dự án của tôi:
/**
* Pass an array, entity or a custom QueryBuilder instance to paginate.
* Takes an array of parameters as a second argument.
* Default parameter values:
*
* $params = array(
* 'curPage' => 1,
* 'perPage' => 15,
* 'order' => 'DESC'
*);
*
* @param mixed $object
* @param array $params
*
* @return Pagerfanta
*/
public function paginate($object, $params = array())
{
if (is_array($object)) {
$adapter = new ArrayAdapter($object);
} elseif ($this->isEntity($object)) {
$qb = $this->em->createQueryBuilder()
->select('s')
->from($this->getEntityName($object), 's')
->orderBy('s.id', isset($params['order']) ? $params['order'] : 'DESC');
$adapter = new DoctrineORMAdapter($qb);
} elseif ($object instanceof QueryBuilder) {
$adapter = new DoctrineORMAdapter($object);
}
$pager = new Pagerfanta($adapter);
$pager->setMaxPerPage(isset($params['perPage']) ? $params['perPage'] : 15);
$pager->setCurrentPage(isset($params['curPage']) ? $params['curPage'] : 1);
return $pager;
}
Bạn có thể vượt qua một mảng, tổ chức hoặc một trường hợp xây dựng truy vấn và nó sẽ trả về một đối tượng thích hợp paginated sẵn sàng để sử dụng.
Bạn có biết làm thế nào nó được thực hiện, nhưng dù sao, đây là những gì tôi có trong kho thực thể của tôi - một hàm trả về Ví dụ xây dựng truy vấn (hoàn hảo cho pagerfanta), lợi nhuận khác một mảng được sử dụng ở những nơi khác:
public function getMessageQueryBuilder($campaignId, $eqCriteriaArray = array(), $neqCriteriaArray = array())
{
$qb = $this->createQueryBuilder('m');
$qb->select('m')
->leftJoin('m.campaign', 'c')
->leftJoin('m.sentBy', 'u')
->where($qb->expr()->eq('m.campaign', $campaignId));
foreach ($eqCriteriaArray as $property => $value) {
$qb->andWhere($qb->expr()->eq($property, $qb->expr()->literal($value)));
}
foreach ($neqCriteriaArray as $property => $value) {
$qb->andWhere($qb->expr()->neq($property, $qb->expr()->literal($value)));
}
return $qb->orderBy('m.id', 'DESC');
}
public function filterMessages($campaignId, $eqCriteriaArray = array(), $neqCriteriaArray = array())
{
return $this->getMessageQueryBuilder($campaignId, $eqCriteriaArray, $neqCriteriaArray)->getQuery()->getResult();
Sau đó, tôi kết hợp hai để có được những đối tượng pager thực tế:
$singleSmsPager = $this->pagerUtil->paginate(
$this->em->getRepository('TreasureForgeMessageBundle:Message')
->getMessageQueryBuilder(CcToolSender::CAMPAIGN_ID, array(), array('u.username' => 'admin')),
array(
'curPage' => $singleSmsPage,
'perPage' => 10
)
);
Nếu bạn thấy đoạn mã tạo ra một truy vấn phức tạp không cần thiết, có lẽ bạn nên viết một báo cáo lỗi tại trang web của dự án. – lxg