Как сортировать метод findAll Doctrine
Я читал документацию доктрины, но я не смог найти способ сортировки результатов findAll ().
Я использую Symfony2 + доктрину, это утверждение, которое я использую внутри моего контроллера:
$this->getDoctrine()->getRepository('MyBundle:MyTable')->findAll();
но я хочу, чтобы результаты, которые должны быть упорядочены по возрастанию имен.
Я пытаюсь передать массив в качестве аргумента таким образом:
findAll( array('username' => 'ASC') );
но это не работает (он не жалуется любой.)
есть ли способ сделать это без создания запроса DQL?
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();
иногда полезно посмотреть на исходный код.
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; });
это быстрее, чем ПРИКАЗОМ предложение, и без накладных расходов итератора.