2013-09-30 3 views
18

Come posso contare gli elementi di un'entità con una condizione in Doctrine? Ad esempio, mi rendo conto che posso usare:Doctrina: conteggio di elementi di un'entità con una condizione

Ma questo conterà solo tutti gli utenti. Mi piacerebbe contare solo quelli che hanno un dipendente di tipo. Potrei fare qualcosa del tipo:

$users = $dm->getRepository('User')->findBy(array('type' => 'employee')); 
$users = count($users); 

Questo funziona ma non è ottimale. C'è qualcosa di simile al seguente:?

$usersCount = $dm->getRepository('User')->count()->where('type', 'employee'); 
+2

che è davvero ridicolo che classe repository di base non può contare entità che soddisfano le condizioni semplici. Questa caratteristica dovrebbe sicuramente apparire nella lista dei desideri di Doctrine. – zeliboba

+0

Perché non '$ users = $ dm-> getRepository ('User') -> findBy (array ('type' => 'employee')) -> count();'? –

+1

@BorisK: popolerà tutti gli utenti quindi contano. Non è il modo migliore per farlo. – Bacteries

risposta

18

Beh, è ​​possibile utilizzare il QueryBuilder per impostare una query COUNT:

presumendo che $dm è il vostro gestore di entità.

$qb = $dm->createQueryBuilder(); 

$qb->select($qb->expr()->count('u')) 
    ->from('User', 'u') 
    ->where('u.type = ?1') 
    ->setParameter(1, 'employee'); 

$query = $qb->getQuery(); 

$usersCount = $query->getSingleScalarResult(); 

Oppure si può semplicemente scrivere in DQL:

$query = $dm->createQuery("SELECT COUNT(u) FROM User u WHERE u.type = ?1"); 
$query->setParameter(1, 'employee'); 

$usersCount = $query->getSingleScalarResult(); 

I conteggi potrebbero aver bisogno di essere sul campo id, piuttosto che l'oggetto, non ricordo. In tal caso, è sufficiente cambiare il COUNT(u) o il ->count('u') in COUNT(u.id) o ->count('u.id') o qualunque sia il nome del campo della chiave primaria.

+1

In realtà stavo cercando di evitarlo, ma immagino che non ci sia altro modo per farlo. Grazie. – luqita

+1

@luqita: evitare cosa esattamente - una query? Questo eseguirà una query aggregata sul server del database, che è il modo più efficiente per ottenere quei dati in generale. Sei più preoccupato di evitare la digitazione? È possibile estendere il gestore di entità per fornire un metodo di convenienza del tipo specificato. – Orbling

3

Questa domanda ha 3 anni ma c'è un modo per mantenere la semplicità di findBy() per contare con criteri.

Sulla vostra repository è possibile aggiungere questo metodo:

public function countBy(array $criteria) 
    { 
     $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName); 
     return $persister->count($criteria); 
    } 

Così il vostro codice sarà simile a questo:

$criteria = ['type' => 'employee']; 
$users = $repository->findBy($criteria, ['name' => 'ASC'], 0, 20); 
$nbUsers = $repository->count($criteria); 
+1

Sarebbe bene, se funzionasse. Su Symfony 2.7 solleva un'eccezione ... "Tentativo di chiamare un metodo non definito denominato" count "della classe" Doctrine \ ORM \ Persisters \ BasicEntityPersister "" –

+0

In realtà, il metodo count() su EntityPersister è disponibile da Doctrine ORM 2.3 (quindi è disponibile solo da Symfony 2.8). Aggiorna il tuo symfony a 2.8 ti darà una versione LTS e questo metodo;) – Bacteries

+0

Ah, questo spiegherebbe. Per quanto riguarda la migrazione a 2.8x, sì, mi piacerebbe moltissimo - purtroppo nel nostro sistema c'è bisogno di un sacco di refactoring! Succederà alla fine però, 2.7 ha solo 12 mesi di supporto rimasti. –