2012-01-21 13 views
16

Questa può sembrare una richiesta rudimentale, ma non riesco a farlo funzionare, quindi mi manca qualcosa di stupido o non capisco come dovrebbe essere fatto. Grazie in anticipo.Doctrine 2.1 DQL - Valori multipli di query many-to-many - Articolo in più categorie?

Ho due entità di dottrina con una relazione molti-a-molti: Articoli e Categorie. A cui si aggiungono items_has_categories.

/** 
* Item 
* 
* @Table(name="items") 
* @Entity(repositoryClass="Entity\Repository\Item") 
*/ 
class Item 
{ 

.... 

/** 
* @var Categories 
* 
* @ManyToMany(targetEntity="Categorie", inversedBy="items", cascade={"persist"}) 
* @JoinTable(name="items_has_categories", 
* joinColumns={ 
*  @JoinColumn(name="items_id", referencedColumnName="id") 
* }, 
* inverseJoinColumns={ 
*  @JoinColumn(name="categories_id", referencedColumnName="id") 
* } 
*) 
*/ 
private $categories; 

.... 
} 

/** 
* Categorie 
* 
* @Table(name="categories") 
* @Entity(repositoryClass="Entity\Repository\Categorie") 
*/ 
class Categorie 
{ 
..... 

/** 
* @var Items 
* 
* @ManyToMany(targetEntity="Item", mappedBy="categories") 
*/ 
private $items; 

.... 
} 

E quello che sto cercando di fare è eseguire una query per restituire tutti gli oggetti che si trovano in tutta la numero "x" di categorie - che ritengo/pensiero dovrebbe essere un SELECT con e clausola AND:

class Item extends EntityRepository 
{ 
    public function findItemsByCategories($categories) 
    { 

    $qString = 'SELECT j, t, c FROM Technique\Entity\Item j LEFT JOIN j.itemImages t JOIN j.categories c WHERE'; 

    $i = 0; 
    foreach ($categories as $c) 
    { 
     $qString .= ' c.name = ?' . $i; 

     if ($i < (count($categories)-1)) 
     { 
      $qString .= ' AND'; 
     } 
     $i++; 
    } 

    $query = $this->_em->createQuery($qString); 
    $query->setParameters($categories); 

    return $query->getResult(); 
} 

quel po 'di codice ha nessun errore e sputa fuori la seguente query DQL SELECT (quando 2 categorie vengono inviati nella matrice: $ categorie):

SELECT j, t, c FROM Technique\Entity\Item j LEFT JOIN j.itemImages t JOIN j.categories c WHERE c.name = ?0 AND c.name = ?1 

Questo è sempre restituisce un array vuoto , cioè, nessun risultato S. Anche se nel mio DB ci sono più di 20 articoli che corrispondono ai criteri: sono in entrambe le categorie.

Qualcuno vede cosa sto facendo male qui? Questa dovrebbe essere una selezione AND ...? Fondamentalmente vorrei sapere come interrogare una relazione molti-a-molti in Doctrine 2+, dove c'è più di un valore che deve essere soddisfatto ...

risposta

40

Per chiunque fosse interessato, l'ho capito (dolorosamente). Doctrine dovrebbe davvero spiegarlo meglio invece della sola riga che hanno sulla pagina DQL ...

Fondamentalmente non è una query AND, è una query MEMBER OF AND. Per ogni categoria un membro della deve essere creato e poi ha aggiunto a tutta la query con un AND:

SELECT j, t FROM Entity\Item j LEFT JOIN j.itemImages t WHERE ?0 MEMBER OF j.categories AND ?1 MEMBER OF j.categories AND ?2 MEMBER OF j.categories, etc. 

che restituirà tutti gli elementi che sono in tutte le categorie richieste.

+1

Grazie per aver condiviso la tua ricerca. Stavo per rinunciare a un problema molto simile, ma MEMBER OF ha fatto il trucco. Meglio per te. –

+1

Finalmente un bel modo per farlo. IL MEMBRO dovrebbe davvero essere più documentato. Non sapevo nemmeno che esistesse. Molte grazie. – ZolaKt

+1

Dai miei esperimenti, questo metodo causerà l'esecuzione di più sottoquery. Se DQL lo accetta, starai molto meglio con una sub-query e una clausola WHERE che usa IN(). Sperimenterò e posterò una risposta se questo funziona ancora in DQL. – Lewis

Problemi correlati