2010-07-09 8 views
14

Sto sperimentando con Doctrine ORM (v1.2) per PHP. Ho definito un "liquore" di classe, con due classi di bambini "gin" e "whisky". Uso l'ereditarietà concreta (ereditarietà delle tabelle di classe nella maggior parte della letteratura) per mappare le classi a tre tabelle di database separate.PHP doctrine 1.2 ORM - query polimorfiche con ereditarietà delle tabelle di classe

Sto tentando di eseguire il seguente:

$liquor_table = Doctrine_Core::getTable('liquor'); 
$liquors = $liquor_table->findAll(); 

Inizialmente, mi aspettavo $ liquori di essere un Doctrine_Collection contenente tutti i liquori, siano essi whisky o gin. Ma quando eseguo il codice, ottengo una collezione vuota, nonostante abbia diverse righe nelle tabelle del database whisky e gin. Sulla base dell'SQL generato, capisco perché: l'ORM sta interrogando la tabella "liquore" e non le tabelle whisky/gin in cui sono memorizzati i dati effettivi.

Si noti che il codice funziona perfettamente quando si passa il tipo di ereditarietà all'aggregazione di colonne (ereditarietà semplice della tabella).

Qual è il modo migliore per ottenere un Doctrine_Collection contenente tutti i liquori?

Aggiornamento

Dopo qualche ricerca, sembra che io mi aspetto dottrina da eseguendo un'operazione di SQL UNION dietro le quinte per combinare i set di risultati dal "whiskey" e le tabelle "gin".

Questa è una query polimorfa .

In base a this ticket, questa funzionalità non è disponibile in Doctrine 1.x. È destinato alla versione 2.0. (vedi anche Doctrine 2.0 docs per CTI).

Quindi, alla luce di queste informazioni, quale sarebbe il modo più pulito e più efficace per ovviare a questa carenza? Passa all'ereditarietà di una tabella singola? Esegui due query DQL e unisci manualmente il risultato Doctrine_Collections?

risposta

3

l'unica modalità di ereditarietà stabile e utile di Doctrine per il momento è column_aggregation. Ho provato gli altri in diversi progetti. Con column_aggregation puoi imitare query polimorfiche. L'ereditarietà in generale è qualcosa di buggato in Doctrine (1.x). Con 2.x questo cambierà, quindi potremmo avere opzioni migliori in futuro.

0

Ho scritto l'inizio (non pronto per la produzione) di un ORM che farebbe esattamente quello che stai cercando da un po 'di tempo fa. Solo per poter avere una dimostrazione del concetto. Tutti i miei studi hanno dimostrato che stai in qualche modo mescolando codice e dati (informazioni sulla sottoclasse nella tabella dei liquori).

Quindi, ciò che si potrebbe fare è scrivere un metodo sulla classe di classe/classe liquore che interroga la propria tabella. Il modo migliore per farla franca con senza dover codificare tutte le sottoclassi nella classe liquore consiste nell'avere una colonna che contiene il nome della classe della sottoclasse in essa contenuta.

Il modo in cui diffondi i dettagli è interamente a te. Penso che il modo più normale (e chiunque possa correggermi se sbaglio qui) sia di memorizzare tutti i campi che appaiono nella tua classe di liquori nel tavolo dei liquori. Quindi, per ciascuna sottoclasse, disporre di una tabella che memorizzi i dati specifici che appartengono al tipo di sottoclasse. Qual è il punto in cui si mescolano codice e dati perché il codice sta leggendo la tabella liquori per ottenere il nome della sottoclasse per eseguire un join.

userò auto & biciclette e alcune differenze minime, ma banali tra di loro per il mio esempio:

Ride 
---- 
id 
name 
type 

(1, 'Sebring', 'Car') 
(2, 'My Bike', 'Bicycle') 

Bicycle 
------- 
id 
bike_chain_length 

(2, '2 feet') 

Car 
--- 
id 
engine_size 

(1, '6 cylinders') 

Ci sono tutti i tipi di variazioni da qui in avanti come la memorizzazione di tutti i dati della classe di liquori nella tabella sottoclasse e solo memorizzando i riferimenti e i nomi delle sottoclassi nella tabella dei liquori. Mi piace il meno perché però, se si aggregano i dati comuni, si evita di dover interrogare ogni tabella delle sottoclassi per i campi comuni.

Spero che questo aiuti!

Problemi correlati