2013-09-30 16 views
18

Jak mogę policzyć przedmioty jednostki z warunkiem w Doctrine? Na przykład, zdaję sobie sprawę, że mogę użyć:Doctrine: Liczenie pozycji podmiotu pod warunkiem

$usersCount = $dm->getRepository('User')->count(); 

Ale to tylko policzy wszystkich użytkowników. Chciałbym policzyć tylko tych, którzy mają pracownika typu. Mogę zrobić coś takiego:

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

To działa, ale nie jest optymalne. Czy jest coś takiego:?

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

To jest naprawdę śmieszne, że podstawowa klasa repozytorium nie może liczyć podmiotów spełniających prostych warunków. Ta funkcja zdecydowanie powinna pojawić się na liście życzeń Doctrine. – zeliboba

+0

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

+1

@BorisK: zapełni wszystkich użytkowników, a następnie policz. Nie jest to najlepszy sposób na zrobienie tego. – Bacteries

Odpowiedz

18

Cóż, można użyć QueryBuilder Aby ustawić COUNT zapytanie:

Zakładając, że $dm jest Twój kierownik jednostki.

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

Albo można po prostu napisać go w DQL:

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

$usersCount = $query->getSingleScalarResult(); 

Liczy może trzeba być na polu id, zamiast obiektu, nie mogę sobie przypomnieć. Jeśli tak, po prostu zmień wartość COUNT(u) lub ->count('u') na COUNT(u.id) lub dowolne inne pole klucza podstawowego.

+1

Próbowałem tego uniknąć, ale chyba nie ma innego sposobu, aby to zrobić. Dziękuję Ci. – luqita

+1

@luqita: Unikaj dokładnie tego - zapytania? Spowoduje to wykonanie zagregowanej kwerendy na serwerze bazy danych, co jest najskuteczniejszym sposobem generowania tych danych. Czy bardziej zależy Ci na unikaniu pisania na klawiaturze? Można rozszerzyć menedżer encji, aby zapewnić wygodną metodę określonego typu. – Orbling

3

To pytanie ma 3 lata, ale istnieje sposób na zachowanie prostoty metody findBy() dla zliczania kryteriów.

Na repozytorium można dodać tę metodę:

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

Więc twój kod będzie wyglądać następująco:

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

Byłoby dobrze, gdyby zadziałało. W Symfony 2.7 wywołuje wyjątek ... "Próba wywołania niezdefiniowanej metody o nazwie" count "klasy" Doctrine \ ORM \ Persisters \ BasicEntityPersister "" –

+0

W rzeczywistości metoda count() w EntityPersister jest dostępna od czasu Doctrine ORM 2.3 (więc jest dostępny tylko od Symfony 2.8). Uaktualnij swoją symfonię do wersji 2.8, a otrzymasz wersję LTS i tę metodę;) – Bacteries

+0

Ach, to by to wyjaśniło. Jeśli chodzi o migrację do 2,8x, tak, bardzo bym chciał - niestety w naszym systemie jest sporo refaktoryzacji! W końcu tak się stanie, 2.7 ma tylko 12 miesięcy wsparcia. –