Come utilizzare un metodo findBy con criteri comparativi

Avrei bisogno di usare un finder "magic finder" usando i criteri comparativi (non solo i criteri esatti). In altre parole, ho bisogno di fare qualcosa del genere:

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

in modo da get tutti gli acquisti in cui il premio è superiore a 200.

Questo è un esempio che utilizza la class Expr () – Ne avevo bisogno anche alcuni giorni fa e mi ci è voluto del tempo per scoprire qual è la syntax esatta e il modo di utilizzo:

 /** * fetches Products that are more expansive than the given price * * @param int $price * @return arrays */ public function findProductsExpensiveThan($price) { $em = $this->getEntityManager(); $qb = $em->createQueryBuilder(); $q = $qb->select(arrays('p')) ->from('YourProductBundle:Product', 'p') ->where( $qb->expr()->gt('p.price', $price) ) ->orderBy('p.price', 'DESC') ->getQuery(); return $q->getResult(); } 

La class Doctrine\ORM\EntityRepository implementa l' Doctrine\ORM\EntityRepository Doctrine\Common\Collections\Selectable .

L'interface Selectable è molto flessibile e abbastanza nuova, ma ti permetterà di gestire facilmente confronti e criteri più complessi su entrambi i repository e le singole raccolte di elementi, indipendentemente se in ORM o ODM o problemi completamente separati.

Questo sarebbe un criterio di confronto appena richiesto come in Doctrine ORM 2.3.2 :

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

Il vantaggio principale di questa API è che stai implementando una sorta di model di strategia qui e funziona con repository, raccolte, raccolte pigre e ovunque sia implementata l'API Selectable .

Questo ti permette di sbarazzarti di dozzine di methods speciali che hai scritto per i tuoi repository (come findOneBySomethingWithParticularRule ), e invece di concentrarti sulla scrittura delle tue classi di criteri, ognuna delle quali rappresenta uno di questi particolari filtri.

Devi usare DQL o QueryBuilder . Ad esempio nel tuo Purchase- EntityRepository potresti fare qualcosa del genere:

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

Per scenari ancora più complessi dai un'occhiata alla class Expr () .

La documentazione di Symfony ora mostra esplicitamente come fare questo:

 $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(); 

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

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