2011-11-09 15 views
5

Nella mia applicazione, ho un numero di semplici tabelle di riferimento/consultazione database utilizzate per fornire un elenco di valori consentiti in una tabella correlata.Evitare join a Reference/Lookup Tables in Doctrine 2

(si sa, tavolo un 'Paesi' ha un elenco di paesi che sono consentiti nel campo 'Paese' della tabella Indirizzo ...)

Per mantenere il mio modello di dati quanto più snella possibile, ho utilizzare "Bill Karwin technique" per ignorare la colonna "id" nella tabella di ricerca e utilizzare semplicemente il valore effettivo come chiave primaria. In questo modo, non è necessario eseguire un join per ottenere il valore nella tabella principale perché è già presente come chiave esterna.

Il problema è che Doctrine utilizza riferimenti a oggetti per tutte le associazioni, il che significa che le query richiedono ancora join alle tabelle di ricerca, anche quando la tabella principale ha già i valori che mi servono.

Ad esempio, la query non funzionare:

$qb->select(array('a.id', 'a.street', 'a.city', 'a.country')) 
    ->from('Entity\Address', 'a'); 

Invece, quello che dovete fare questo:

$qb->select(array('a.id', 'a.street', 'a.city', 'c.country')) 
    ->from('Entity\Address', 'a') 
    ->join('a.country', 'c'); 

In caso contrario si ottiene questo errore:. "PathExpression valido Deve essere uno StateFieldPathExpression ".

Sommare tutti i join necessari per le tabelle di ricerca e c'è un sacco di costi inutili nelle mie query.

Qualcuno sa un buon modo per evitare di dover eseguire join a ricerche/tabelle di riferimento in Doctrine 2?

(PS - Preferirei evitare di utilizzare ENUM, come sono not supported by Doctrine e hanno altri well-documented disadvantages.)

risposta

6

Sì, questo genere di schifo, ma credo che avevano una buona ragione per fare in modo che modo.

È possibile utilizzare l'hint HINT_INCLUDE_META_COLUMNS. Comprenderà tutti i campi nel risultato della query, incluse le chiavi esterne che vengono mappate come relazioni.

$query = \Doctrine::em()->createQuery($queryString) 
    ->setParameters($params) 
    ->setHint(\Doctrine\ORM\Query::HINT_INCLUDE_META_COLUMNS, TRUE); 

Quindi, se il vostro avete un campo city_id nella tabella Address nel db, sarà anche emessi nel risultato della query, insieme con la relazione "standard" City.

+0

Questo è fantastico - non sapevo del metodo setHint() e ho intenzione di utilizzarlo. – cantera

+1

Il set hint viene utilizzato per tutti i tipi di elementi, non solo per includere le meta colonne. È un modo per allegare un walker di query che viene eseguito con ogni tua query. Puoi anche creare i tuoi suggerimenti, che fanno ciò che vuoi. Bella piccola cosa non lo è;) – ZolaKt

+0

Attenzione: la dottrina non include le chiavi esterne che contengono null. Come se city_id non fosse obbligatorio, non sarà sempre presente. Spendi solo 2 ore, pensando che fosse un problema con la cache :) –