2011-11-30 33 views
48

È possibile filtrare i risultati da un arrayCollection in Doctrine 2 mentre si utilizza il caricamento lazy? Ad esempio,Doctrine 2 ArrayCollection filter method

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

Non è chiaro per me come sia effettivamente utilizzato il metodo di filtro.

+0

Ma il metodo ancora carica su molti dati, ad esempio per conteggio, carica tutti i dati corrispondenti. –

risposta

66

La risposta Boris Guéry a questo post, può aiutare: Doctrine 2, query inside entities

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

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

L'unico problema con il metodo di filtro è che devi recuperare tutti i dati prima di poterlo filtrare, sai se c'è un modo per farlo senza recuperare tutto? – Dennis

+0

Ciao - Sto provando quanto sopra ma ricevendo un errore di sintassi, puoi aggiornare la tua risposta? – Sjwdavies

+0

@Sjwdavies L'ho aggiornato per te. Manca() attorno a $ idsToFilter. – Jrgns

12

vostro caso d'uso potrebbe essere:

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

se si aggiunge -> prima() si otterrà è tornata solo la prima voce, che non è ciò che desideri.

@ Sjwavies È necessario inserire() attorno alla variabile passata a USE. È inoltre possibile ridurre il ritorno in_array è un valore booleano già:

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

Il metodo Collection#filter davvero carico desideroso tutti i membri. Il filtro a livello SQL verrà aggiunto in doc. 2.3.

+1

è vero ora che 2.3 è fuori? Non l'ho trovato nei documenti. Possiamo ora fare cose come il filtro e altre cose, aspettando che la raccolta applichi il filtro alla query e rinvii la query? – Pinetree

+0

@Pinetree Almeno lo dicono così: http://docs.doctrine-project.org/en/latest/reference/working-with-associations.html#filtering-collections – Robin

101

Doctrine ora ha Criteria che offre un'unica API per il filtraggio di raccolte con SQL e in PHP, a seconda del contesto.

http://docs.doctrine-project.org/en/latest/reference/working-with-associations.html#filtering-collections

Aggiornamento

Questo sarà raggiungere il risultato nella risposta accettata, senza ottenere tutto dal database.

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); 
    } 
} 
+0

Grazie per cancellare questo in realtà cambierà la query sql , piuttosto che selezionare tutto dal database e quindi applicare un filtro tramite un ciclo! – tftd

+0

http: // stackoverflow.it/questions/35358597/in-predicate-with-criteria-filtering-isnt-working per favore, dai un'occhiata qui :) – DonCallisto

+0

Sembra esserci un problema quando si usa 'indexBy =" xxx "' su un insieme e chiamando 'matching 'su di esso, dove gli indici vengono scartati. https://github.com/doctrine/doctrine2/issues/4693 – fyrye