93 votes

Comment utiliser une méthode findBy avec des critères comparatifs ?

J'aurais besoin d'utiliser une méthode findBy "magic finder" utilisant des critères comparatifs (et pas seulement des critères exacts). En d'autres termes, j'ai besoin de faire quelque chose comme ceci :

$result = $purchases_repository->findBy(array("prize" => ">200"));

pour que j'obtienne tous les achats dont le prix est supérieur à 200.

230voto

Ocramius Points 10275

La classe Doctrine\ORM\EntityRepository met en œuvre Doctrine\Common\Collections\Selectable API.

En Selectable est très flexible et assez nouvelle, mais elle vous permettra de gérer facilement les comparaisons et les critères plus complexes à la fois sur les référentiels et les collections uniques d'éléments, indépendamment du fait que ce soit dans ORM ou ODM ou des problèmes complètement séparés.

Il s'agirait d'un critère de comparaison comme vous venez de le demander dans Doctrine ORM. 2.3.2 :

$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where(\Doctrine\Common\Collections\Criteria::expr()->gt('prize', 200));

$result = $entityRepository->matching($criteria);

Le principal avantage de cette API est que vous mettez en œuvre une sorte de modèle de stratégie et qu'elle fonctionne avec les référentiels, les collections, les collections paresseuses et partout où l'API est utilisée. Selectable est mise en œuvre.

Cela vous permet de vous débarrasser de dizaines de méthodes spéciales que vous avez écrites pour vos dépôts (telles que findOneBySomethingWithParticularRule ), et concentrez-vous plutôt sur l'écriture de vos propres classes de critères, chacune représentant un de ces filtres particuliers.

35voto

con Points 769

Il s'agit d'un exemple utilisant le Classe Expr() - J'en ai eu besoin aussi il y a quelques jours et il m'a fallu du temps pour trouver la syntaxe exacte et le mode d'utilisation :

/**
 * fetches Products that are more expansive than the given price
 * 
 * @param int $price
 * @return array
 */
public function findProductsExpensiveThan($price)
{
  $em = $this->getEntityManager();
  $qb = $em->createQueryBuilder();

  $q  = $qb->select(array('p'))
           ->from('YourProductBundle:Product', 'p')
           ->where(
             $qb->expr()->gt('p.price', $price)
           )
           ->orderBy('p.price', 'DESC')
           ->getQuery();

  return $q->getResult();
}

9voto

dbrumann Points 3669

Vous devez utiliser soit DQL ou le QueryBuilder . Par exemple, dans votre achat- EntityRepository vous pourriez faire quelque chose comme ça :

$q = $this->createQueryBuilder('p')
          ->where('p.prize > :purchasePrize')
          ->setParameter('purchasePrize', 200)
          ->getQuery();

$q->getResult();

Pour des scénarios encore plus complexes, jetez un coup d'œil à l'outil de gestion de l'information de la Commission européenne. Classe Expr() .

6voto

$criteria = new \Doctrine\Common\Collections\Criteria();
    $criteria->where($criteria->expr()->gt('id', 'id'))
        ->setMaxResults(1)
        ->orderBy(array("id" => $criteria::DESC));

$results = $articlesRepo->matching($criteria);

4voto

Jeff Clemens Points 318

La documentation de Symfony montre maintenant explicitement comment faire cela :

$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
    'SELECT p
    FROM AppBundle:Product p
    WHERE p.price > :price
    ORDER BY p.price ASC'
)->setParameter('price', '19.99');    
$products = $query->getResult();

De http://symfony.com/doc/2.8/book/doctrine.html#querying-for-objects-with-dql

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X