2010-07-09 29 views
14

Estoy experimentando con el ORM de Doctrine (v1.2) para PHP. Definí una clase "licor", con dos clases de niños "gin" y "whisky". Estoy usando la herencia concreta (herencia de tabla de clase en la mayoría de la literatura) para mapear las clases en tres tablas separadas de la base de datos.PHP doctrine 1.2 ORM - consultas polimórficas con herencia de tabla de clases

Estoy intentando ejecutar lo siguiente:

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

Inicialmente, esperaba $ licores para ser un Doctrine_Collection que contiene todos los licores, ya se trate de whisky o ginebra. Pero cuando ejecuto el código, obtengo una colección vacía, a pesar de tener varias filas en las tablas de base de datos de whisky y gin. Basado en el SQL generado, entiendo por qué: el ORM está consultando la tabla de "licor", y no las tablas de whisky/gin donde se almacenan los datos reales.

Tenga en cuenta que el código funciona perfectamente cuando cambio el tipo de herencia a la agregación de columnas (herencia simple de tablas).

¿Cuál es la mejor manera de obtener una Doctrine_Collection que contenga todos los licores?

actualización

Después de algunas investigaciones más, parece que estoy esperando a ser Doctrina realizando una operación de SQL UNION entre bastidores para combinar los conjuntos de resultados de las tablas "ginebra" "whisky" y.

Esto se conoce como consulta polimórfica.

De acuerdo con this ticket, esta funcionalidad no está disponible en Doctrine 1.x. Está destinado para la versión 2.0. (también vea Doctrine 2.0 docs para CTI).

Por lo tanto, a la luz de esta información, ¿cuál sería la forma más limpia y eficiente de evitar esta deficiencia? ¿Cambiar a herencia de tabla única? ¿Realiza dos consultas DQL y fusiona manualmente las Doctrine_Collections resultantes?

Respuesta

3

el único modo de herencia heredable y útil de Doctrine para el momento es column_aggregation. He probado otros en diferentes proyectos. Con column_aggregation puedes imitar consultas polimórficas. La herencia en general es algo que tiene errores en Doctrine (1.x). Con 2.x esto cambiará, por lo que es posible que tengamos mejores opciones en el futuro.

0

Escribí los comienzos (no listos para producción) de un ORM que harían exactamente lo que está buscando hace un tiempo. Solo para poder tener una prueba de concepto. Todos mis estudios indicaron que de alguna manera estás mezclando código y datos (información de subclase en la tabla de licor).

Así que lo que podrías hacer es escribir un método en tu clase/clase de licor que consulta su propia tabla. La mejor manera de salirse con sin tener que codificar todas las subclases en su clase de licor es tener una columna que contenga el nombre de clase de la subclase en ella.

La forma de difundir los detalles depende exclusivamente de usted. Creo que la manera más normalizada (y cualquiera puede corregirme si estoy equivocado aquí) es almacenar todos los campos que aparecen en tu clase de licor en la mesa de licor. Luego, para cada subclase, tenga una tabla que almacene los datos específicos que pertenecen al tipo de subclase. Cuál es el punto en el que está mezclando código y datos porque su código está leyendo la tabla de licor para obtener el nombre de la subclase para realizar una combinación.

Voy a usar coches & bicicletas y algunas diferencias mínimas, sin embargo triviales entre ellos para mi ejemplo:

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') 

Hay todo tipo de variaciones de aquí en adelante como el almacenamiento de todos los datos de la clase de licor en la tabla de la subclase y solo almacena referencias y nombres de subclases en la tabla de licor. Sin embargo, me gusta menos porque si agrega los datos comunes, le evita tener que consultar cada tabla de subclase para los campos comunes.

Espero que esto ayude!

Cuestiones relacionadas