Как сортировать метод findAll Doctrine


Я читал документацию доктрины, но я не смог найти способ сортировки результатов findAll ().

Я использую Symfony2 + доктрину, это утверждение, которое я использую внутри моего контроллера:

$this->getDoctrine()->getRepository('MyBundle:MyTable')->findAll();

но я хочу, чтобы результаты, которые должны быть упорядочены по возрастанию имен.

Я пытаюсь передать массив в качестве аргумента таким образом:

findAll( array('username' => 'ASC') );

но это не работает (он не жалуется любой.)

есть ли способ сделать это без создания запроса DQL?

11 88

11 ответов:

как показано на рисунке @Lighthart, да, это возможно, хотя он добавляет значительный жир к контроллеру и не является сухим.

вы действительно должны определить свой собственный запрос в репозитории сущностей, это просто и лучшая практика.

use Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository
{
    public function findAll()
    {
        return $this->findBy(array(), array('username' => 'ASC'));
    }
}

затем вы должны сказать вашей сущности искать запросы в репозитории:

/**
 * @ORM\Table(name="User")
 * @ORM\Entity(repositoryClass="Acme\UserBundle\Entity\Repository\UserRepository")
 */
class User
{
    ...
}

наконец, в вашем контроллере:

$this->getDoctrine()->getRepository('AcmeBundle:User')->findAll();
$this->getDoctrine()->getRepository('MyBundle:MyTable')->findBy([], ['username' => 'ASC']);

иногда полезно посмотреть на исходный код.

findAll реализация очень простая (vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php):
public function findAll()
{
    return $this->findBy(array());
}

Итак, мы смотрим на findBy и найти то, что нам нужно (orderBy)

public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)

просто:

$this->getDoctrine()->getRepository('AcmeBundle:User')->findBy(
    array(),
    array('username' => 'ASC')
);

это работает для меня:

$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(),array('name' => 'ASC'));

сохранение первого массива пустым возвращает все данные, это сработало в моем случае.

вы должны использовать критерии, например:

<?php

namespace Bundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\Common\Collections\Criteria;

/**
* Thing controller
*/
class ThingController extends Controller
{
    public function thingsAction(Request $request, $id)
    {
        $ids=explode(',',$id);
        $criteria = new Criteria(null, <<DQL ordering expression>>, null, null );

        $rep    = $this->getDoctrine()->getManager()->getRepository('Bundle:Thing');
        $things = $rep->matching($criteria);
        return $this->render('Bundle:Thing:things.html.twig', [
            'entities' => $things,
        ]);
    }
}

посмотрите на исходный код API доктрины:

class EntityRepository{
  ...
  public function findAll(){
    return $this->findBy(array());
  }
  ...
}

вы можете отсортировать существующую коллекцию ArrayCollection с помощью итератора массива.

предполагая, что $collection - это ваша коллекция ArrayCollection, возвращенная findAll ()

$iterator = $collection->getIterator();
$iterator->uasort(function ($a, $b) {
    return ($a->getPropery() < $b->getProperty()) ? -1 : 1;
});
$collection = new ArrayCollection(iterator_to_array($iterator));

Это можно легко превратить в функцию, которую вы можете поместить в свой репозиторий, чтобы создать метод findAllOrderBy ().

Я использую альтернативу решению, которое написал nifr.

$resultRows = $repository->fetchAll();
uasort($resultRows, function($a, $b){
    if ($a->getProperty() == $b->getProperty()) {
        return 0;
    }
    return ($a->getProperty()< $b->getProperty()) ? -1 : 1;
});

это быстрее, чем ПРИКАЗОМ предложение, и без накладных расходов итератора.

попробуйте это:

$em = $this->getDoctrine()->getManager();

$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(), array('username' => 'ASC'));

измените функцию findAll по умолчанию в EntityRepository следующим образом:

public function findAll( array $orderBy = null )
{
    return $this->findBy([], $orderBy);
}

таким образом, вы можете использовать "findAll" для любого запроса для любой таблицы данных с возможностью сортировки запроса