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

Я читал документацию Doctrine, но мне не удалось найти способ поиска findAll() Results.

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

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

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

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

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

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

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

Ответ 1

Как @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();

Ответ 2

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

Ответ 3

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

Например, реализация 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)

Ответ 4

Простой:

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

Ответ 5

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

<?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,
        ]);
    }
}

Ответ 6

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

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

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

Ответ 7

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

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

Ответ 8

Вы можете отсортировать существующий массив 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().

Ответ 9

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

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

Это быстрее, чем предложение ORDER BY, и без накладных расходов на Iterator.

Ответ 10

Попробуйте следующее:

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

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