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

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

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

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

61
demandé sur j0k 2013-02-09 14:01:49

5 réponses

ceci est un exemple utilisant la classe Expr () - j'en avais besoin aussi il y a quelques jours et il m'a fallu un certain temps pour trouver quelle est 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();
}
29
répondu con 2013-02-09 12:58:43

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

l'interface Selectable est très flexible et assez nouvelle, mais elle vous permettra de traiter des comparaisons et des critères plus complexes facilement sur les deux dépôts et les collections uniques d'articles, indépendamment si dans ORM ou ODM ou des problèmes complètement séparés.

ce serait un critère de comparaison comme vous venez de le demander comme dans Doctrine ORM 2.3.2 :

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

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

le principal avantage de cette API est que vous mettez en œuvre une sorte de schéma de stratégie ici, et qu'elle fonctionne avec des dépôts, des collections, des collections paresseuses et partout où l'API Selectable est implémentée.

cela vous permet de vous débarrasser de dizaines de méthodes spéciales que vous avez écrites pour vos dépôts (comme findOneBySomethingWithParticularRule ), et au lieu de se concentrer sur l'écriture de vos propres classes de critères, chacun représentant un de ces filtres.

157
répondu Ocramius 2013-02-10 18:30:38

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

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

$q->getResult();

pour des scénarios encore plus complexes, regardez la classe Expr () .

6
répondu dbrumann 2013-02-09 13:43:08

la documentation Symfony montre maintenant explicitement comment faire ceci:

$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

3
répondu Jeff Clemens 2016-04-18 16:33:11
$criteria = new \Doctrine\Common\Collections\Criteria();
    $criteria->where($criteria->expr()->gt('id', 'id'))
        ->setMaxResults(1)
        ->orderBy(array("id" => $criteria::DESC));

$results = $articlesRepo->matching($criteria);
1
répondu Patrizio Onorati 2017-10-03 15:15:53