web-dev-qa-db-fra.com

Comment trier la méthode findAll Doctrine

J'ai lu la documentation de Doctrine, mais je n'ai pas réussi à trouver un moyen de trier findAll () Results.

J'utilise symfony2 + doctrine, voici l'affirmation que j'utilise dans mon contrôleur:

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

mais je veux que les résultats soient ordonnés par noms d'utilisateurs ascendants.

J'ai essayé de passer un tableau en argument de cette façon:

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

mais ça ne marche pas (ça ne se plaint pas non plus).

Est-il possible de le faire sans créer une requête DQL?

96
ILikeTacos

Comme @ Lighthart comme indiqué, oui, c'est possible, bien que cela ajoute beaucoup de graisse au contrôleur et ne soit pas DRY.

Vous devez vraiment définir votre propre requête dans le référentiel d’entités, c’est une pratique simple et recommandée.

use Doctrine\ORM\EntityRepository;

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

Ensuite, vous devez demander à votre entité de rechercher des requêtes dans le référentiel:

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

Enfin, dans votre contrôleur:

$this->getDoctrine()->getRepository('AcmeBundle:User')->findAll();
198
Pier-Luc Gendreau
$this->getDoctrine()->getRepository('MyBundle:MyTable')->findBy([], ['username' => 'ASC']);
74
Stiig

Il est utile de regarder parfois le code source.

Par exemple, la mise en œuvre de findAll est très simple (vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php):

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

Nous examinons donc findBy et trouvons ce dont nous avons besoin (orderBy)

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

Simple:

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

Cela fonctionne pour moi:

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

Garder le premier tableau vide va récupérer toutes les données, cela a fonctionné dans mon cas.

6
Buttler

Vous devez utiliser un critère, par exemple:

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

Regardez le code source de l'API Doctrine:

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

Essaye ça:

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

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

J'utilise une alternative à la solution qui a écrit nifr.

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

C'est plus rapide que la clause ORDER BY , et sans les frais généraux d'Iterator.

2
Moisés Márquez

Vous pouvez trier un ArrayCollection existant à l'aide d'un itérateur de tableau. 

en supposant que $ collection est votre ArrayCollection renvoyée par findAll ()

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

Cela peut facilement être transformé en une fonction que vous pouvez mettre dans votre référentiel afin de créer la méthode findAllOrderBy ().

2
nifr

la méthode findBy dans Symfony exclut deux paramètres. Le premier est le tableau des champs que vous souhaitez rechercher et le second tableau est le champ de tri et son ordre

public function findSorted()
    {
        return $this->findBy(['name'=>'Jhon'], ['date'=>'DESC']);
    }
0
Shaz

Modifiez la fonction findAll par défaut dans EntityRepository de la manière suivante:

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

De cette façon, vous pouvez utiliser le '' findAll '' sur n'importe quelle requête pour n'importe quelle table de données avec une option pour trier la requête

0
niksa