web-dev-qa-db-de.com

So sortieren Sie die Methode von findAll Doctrine

Ich habe die Dokumentation von Doctrine gelesen, konnte jedoch keine Möglichkeit finden, findAll () -Ergebnisse zu sortieren.

Ich verwende symfony2 + doctrine. Dies ist die Anweisung, die ich in meinem Controller verwende:

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

ich möchte jedoch, dass die Ergebnisse nach aufsteigenden Benutzernamen sortiert werden.

Ich habe versucht, ein Array wie folgt als Argument zu übergeben:

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

aber es funktioniert nicht (es beschwert sich auch nicht).

Gibt es eine Möglichkeit, dies zu tun, ohne eine DQL-Abfrage zu erstellen?

96
ILikeTacos

Wie @Lighthart wie gezeigt, ist es möglich, obwohl es dem Controller erheblichen Fett hinzufügt und nicht DRY ist.

Sie sollten Ihre eigene Abfrage wirklich im Entitäts-Repository definieren. Dies ist eine einfache und bewährte Methode.

use Doctrine\ORM\EntityRepository;

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

Dann müssen Sie Ihrer Entität mitteilen, dass sie im Repository nach Abfragen suchen soll:

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

Zum Schluss in Ihrem Controller:

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

Es ist nützlich, sich manchmal den Quellcode anzusehen.

Zum Beispiel ist die Implementierung von findAll sehr einfach (vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php):

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

Also schauen wir uns findBy an und finden, was wir brauchen (orderBy)

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

Einfach:

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

Das funktioniert für mich:

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

Wenn das erste Array leer bleibt, werden alle Daten zurückgeholt. In meinem Fall hat es funktioniert.

6
Buttler

Sie müssen ein Kriterium verwenden, zum Beispiel:

<?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

Schauen Sie sich den Doctrine API-Quellcode an:

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

Versuche dies:

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

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

Ich benutze eine Alternative zu der Lösung, die NIFR geschrieben hat.

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

Es ist schneller als die Klausel ORDER BY und ohne den Overhead des Iterators.

2

Sie können eine vorhandene ArrayCollection mithilfe eines Array-Iterators sortieren. 

vorausgesetzt, $ collection ist Ihre ArrayCollection, die von findAll () zurückgegeben wird.

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

Dies kann leicht in eine Funktion umgewandelt werden, die Sie in Ihr Repository einfügen können, um die findAllOrderBy () - Methode zu erstellen.

2
nifr

die findBy-Methode in Symfony berücksichtigt zwei Parameter. Das erste ist ein Feld von Feldern, nach dem Sie suchen möchten, und das zweite Feld ist das Sortierfeld und seine Reihenfolge

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

Ändern Sie die standardmäßige findAll-Funktion in EntityRepository wie folgt:

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

Auf diese Weise können Sie '' findAll '' für jede Abfrage für jede Datentabelle mit einer Option zum Sortieren der Abfrage verwenden

0
niksa