web-dev-qa-db-fra.com

Doctrine 2 Méthode de filtrage ArrayCollection

Puis-je filtrer les résultats d'une arrayCollection dans Doctrine 2 tout en utilisant le chargement différé? Par exemple,

// users = ArrayCollection with User entities containing an "active" property
$customer->users->filter('active' => TRUE)->first()

Pour moi, la manière dont la méthode de filtrage est réellement utilisée n'est pas claire.

57
Dennis

La réponse de Boris Guéry à ce billet peut vous aider: Doctrine 2, interrogation à l'intérieur d'entités

$idsToFilter = array(1,2,3,4);

$member->getComments()->filter(
    function($entry) use ($idsToFilter) {
       return in_array($entry->getId(), $idsToFilter);
    }
); 
80
FredRoger

Doctrine a maintenant Criteria qui offre une API unique pour filtrer les collections avec SQL et PHP, en fonction du contexte.

https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#filtering-collections

Mettre à jour

Cela aboutira au résultat dans la réponse acceptée, sans tout obtenir de la base de données.

use Doctrine\Common\Collections\Criteria;

/**
 * @ORM\Entity
 */
class Member {
  // ...
  public function getCommentsFiltered($ids) {
    $criteria = Criteria::create()->where(Criteria::expr()->in("id", $ids));

    return $this->getComments()->matching($criteria); 
  }
}
118
Ryan

Votre cas d'utilisation serait:

    $ArrayCollectionOfActiveUsers = $customer->users->filter(function($user) {
                        return $user->getActive() === TRUE;
                    });

si vous ajoutez -> first (), vous n'aurez que la première entrée renvoyée, ce qui n'est pas ce que vous voulez.

@ Sjwdavies Vous devez mettre () autour de la variable que vous passez à USE. Vous pouvez aussi raccourcir car in_array return est déjà un booléen:

    $member->getComments()->filter( function($entry) use ($idsToFilter) {
        return in_array($entry->getId(), $idsToFilter);
    });
13