2010-07-09 3 views
14

Ich experimentiere mit der Lehre ORM (v1.2) für PHP. Ich habe eine Klasse "Schnaps" definiert, mit zwei Kinderklassen "Gin" und "Whiskey". Ich verwende die konkrete Vererbung (Klassentischvererbung in der meisten Literatur), um die Klassen drei separaten Datenbanktabellen zuzuordnen.PHP Doktrin 1.2 ORM - polymorphe Abfragen mit Klassentabelle Vererbung

Ich versuche, die folgende auszuführen:

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

Anfangs erwartete ich $ Likören ein Doctrine_Collection alle Flotten sein, das, ob sie Whisky oder Gin sein. Aber wenn ich den Code ausführe, bekomme ich eine leere Sammlung, obwohl ich mehrere Reihen in den Whiskey- und Gin-Datenbanktabellen habe. Auf der Grundlage des generierten SQL verstehe ich, warum: Das ORM fragt die "Likör" -Tabelle ab und nicht die Whiskey/Gin-Tabellen, in denen die tatsächlichen Daten gespeichert sind.

Beachten Sie, dass der Code einwandfrei funktioniert, wenn ich den Vererbungstyp auf Spaltenaggregation (einfache Tabellenvererbung) umschalte.

Was ist der beste Weg, um eine Doctrine_Collection zu erhalten, die alle Liköre enthält?

aktualisiert

Nach einiger mehr Forschung, sieht es aus wie ich Lehre mich erwarte einen SQL UNION Betrieb hinter den Kulissen werden die Durchführung der Ergebnissätze aus dem „Whisky“ und „Gin“ Tabellen zu kombinieren.

Dies ist bekannt als polymorphe Abfrage.

Gemäß this ticket ist diese Funktion in Doctrine 1.x nicht verfügbar. Es ist für die Version 2.0 bestimmt. (Siehe Doktrin 2.0 Docs für CTI).

Angesichts dieser Informationen, was wäre der sauberste und effizienteste Weg, um diesen Mangel zu umgehen? Zur Single-Table-Vererbung wechseln? Führen Sie zwei DQL-Abfragen aus und führen Sie die resultierenden Doctrine_Collections manuell zusammen?

Antwort

3

Der einzige stabile und nützliche Vererbungsmodus von Doctrine ist momentan column_aggregation. Ich habe die anderen in verschiedenen Projekten ausprobiert. Mit column_aggregation können Sie polymorphe Abfragen imitieren. Die Vererbung ist in Doctrine (1.x) etwas fehlerhaft. Mit 2.x wird sich das ändern, also könnten wir in Zukunft bessere Optionen haben.

0

Ich schrieb die (nicht produktionsbereiten) Anfänge eines ORM, die genau das tun würden, wonach Sie suchen. Nur damit ich einen Proof of Concept haben konnte. Alle meine Studien haben ergeben, dass Sie in gewisser Weise Code und Daten mischen (Unterklasseninformationen in der Alkoholtabelle).

Also, was Sie tun können, ist eine Methode auf Ihre Alkoholklasse/Tabellenklasse schreiben, die ihre eigene Tabelle abfragt. Der beste Weg, um mit wegzukommen, müssen nicht alle Unterklassen in Ihrem Alkohol Klasse hart Code haben eine Spalte, die den Klassennamen der Unterklasse darin enthält.

Wie Sie die Details verteilen, liegt ganz bei Ihnen. Ich denke, die normalste (und jeder kann mich korrigieren, wenn ich hier falsch liege) Weg, es zu tun ist, alle Felder, die in Ihrem Alkohol-Klasse erscheinen in der Likör-Tabelle zu speichern. Fügen Sie dann für jede Unterklasse eine Tabelle ein, in der die spezifischen Daten des Unterklasse-Typs gespeichert werden. Dies ist der Punkt, an dem Sie Code und Daten mischen, weil Ihr Code die Alkoholtabelle liest, um den Namen der Unterklasse zum Ausführen eines Joins abzurufen.

Ich werde Autos verwenden & Fahrräder und einige minimal, doch unwesentliche Unterschiede zwischen ihnen für mein Beispiel:

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

Es gibt alle Arten von Variationen von hier vorwärts wie alle Flottenklassendaten in der Unterklasse Tabelle zu speichern und speichert nur Referenzen und Unterklassennamen in der Alkohol-Tabelle. Ich mag dies am wenigsten, denn wenn Sie die allgemeinen Daten aggregieren, ersparen Sie es Ihnen, jede Unterklassentabelle für die allgemeinen Felder abzufragen.

Hoffe, das hilft!