2012-06-20 10 views
17

Sto cercando di costruire una query con il generatore di query dottrina che si unisce ad un tavolo non correlata in questo modo:Symfony 2: INNER JOIN sul tavolo non correlata con il generatore di query dottrina

$query = $this->createQueryBuilder('gpr') 
     ->select('gpr, p') 
     ->innerJoin('TPost', 'p') 
     ->where('gpr.contentId = p.contentId') 

Ma questo non lo fa lavoro. Ho ancora un errore:

Error: Identification Variable TPost used in join path expression but was not defined before.

Ho cercato per questo messaggio di errore e tutti hanno risposto di utilizzare l'alias tavolo + attribuire come p.someAttribute. Ma la tabella a cui voglio partecipare non è correlata nella tabella da cui inizio la mia selezione.

come un normale query MySQL vorrei scrivere in questo modo:

SELECT * FROM t_group_publication_rel gpr 
INNER JOIN t_post p 
WHERE gpr.content_id = p.content_id 

Tutte le idee che cosa sto facendo male?

+0

Possiamo usare DQL per eseguire unirsi con oggetti non correlati? Non lo so. Se possibile, è interessante =). – sensorario

+2

Perché non costruisci * solo * una relazione tra questi due, se vuoi unirti a loro? –

+0

In questo caso una relazione non sarebbe sufficiente. Avrei bisogno di relazioni con 3 diverse tabelle e ogni record potrebbe solo impostare un riferimento a 1 di questi 3. –

risposta

51

Oggi stavo lavorando su un compito simile e mi sono ricordato di aver aperto questo problema. Non so da che versione di dottrina funziona ma in questo momento puoi facilmente unire le classi figlie alla mappatura ereditaria. Quindi una query come questa funziona senza alcun problema:

$query = $this->createQueryBuilder('c') 
     ->select('c') 
     ->leftJoin('MyBundleName:ChildOne', 'co', 'WITH', 'co.id = c.id') 
     ->leftJoin('MyBundleName:ChildTwo', 'ct', 'WITH', 'ct.id = c.id') 
     ->orderBy('c.createdAt', 'DESC') 
     ->where('co.group = :group OR ct.group = :group') 
     ->setParameter('group', $group) 
     ->setMaxResults(20); 

comincio la query nella mia classe genitore che sta usando la mappatura eredità. Nel mio post precedente era un punto di partenza diverso ma lo stesso problema se ricordo bene.

Poiché è stato un grosso problema quando ho iniziato questo problema, penso che potrebbe essere anche interessante per altre persone che non lo conoscono.

+0

Grazie! Questo mi ha davvero aiutato, ho cercato per ore. – Assil

+0

se non ho repository 'MyBundleName: ChildTwo', voglio scrivere query con nome tabella, qual è la soluzione? –

+0

@MohammadFareed Il riferimento all'entità non è un repository, è una stringa nel formato ": " O il FQCN della classe di entità, ad es. \ AppBundle \ Entity \ ChildTwo :: class –

0

Un join DQL funziona solo se un'associazione è definita nella mappatura. Nel tuo caso, direi che è molto più facile fare una query nativa e usare ResultSetMapping per popolare i tuoi oggetti.

2
$dql = "SELECT 
    a, md.fisrtName , md.LastName, mj 
    FROM MembersBundle:Memberdata md 
     INNER JOIN MembersBundle:Address a WITH md = a.empID 
     INNER JOIN MembersBundle:Memberjob mj WITH md = mj.memberData 
      ... 
    WHERE 
     a.dateOfChange IS NULL 
    AND WHERE 
     md.someField = 'SomeValue'"; 

return $em->createQuery($dql)->getResult(); 
+1

Sebbene questa risposta non fornisca dettagli richiesti, non c'è nulla da citare poiché la documentazione di Doctrine manca completamente della copertura di questi tipi di join. Questo ha funzionato per me. Conosco abbastanza sql per analizzare ciò che era previsto e non abbastanza dottrina per collegare i punti. – eggmatters

3

join tra le entità senza le associazioni non erano possibili fino alla versione 2.4, in cui è possibile generare un join arbitraria con la seguente sintassi:

$query = $em->createQuery('SELECT u FROM User u JOIN Blacklist b WITH u.email = b.email'); 

Riferimento: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html

+0

È fantastico!Nota che in questo caso è richiesta la clausola 'WITH', altrimenti si verifica un errore di sintassi. Comunque puoi semplicemente usare una condizione fittizia ed essenzialmente ottenere un cross join reale, che DQL non supporta in altro modo. Ad esempio: 'SELECT u FROM User u JOIN Elementi i WITH 0 = 0'. Questo può essere utile per statistiche complesse. – jlh