Doctrine 2 Vererbung Mapping mit Zuordnung
HINWEIS : wenn das, was ich will, ist nicht möglich, ein "nicht möglich" als Antwort akzeptiert werden
In der Doctrine 2 Dokumentation über inheritance mappinges sagt, es gibt 2 Möglichkeiten :
- Single table inheritance (STI)
- Class table inheritance (CTI)
Für beide gibt es die Warnung :
Wenn Sie eine STI - /CTI-Einrichtung, wie eine viele-zu-eins-oder eins-zu-eins-Entität Sie sollten nie eine der Klassen in den oberen Ebenen der erbschaft-Hierarchie als "targetEntity", nur diejenigen, die keine Unterklassen. Ansonsten Lehre NICHT schaffen proxy-Instanzen dieser Entität und wird IMMER laden Sie die Person eifrig.
So, wie kann ich Vorgehen zu verwenden Vererbung eine Zuordnung zu der Basis (abstrakte) Klasse ? (und behalten Sie die performance natürlich)
Beispiel
Benutzer hat viele Pet
(abstrakte Klasse erweitert Dog
oder Cat
).
Was ich tun will :
class User {
/**
* @var array(Pet) (array of Dog or Cat)
*/
private $pets;
}
Wegen der Warnung in der Lehre Dokumentation, sollte ich das tun :
class User {
/**
* @var array(Dog)
*/
private $dogs;
/**
* @var array(Cat)
*/
private $cats;
}
Das ist ärgerlich, da verliere ich die Vorteile von Vererbung !
Hinweis : ich habe nicht fügen Sie die Lehre Annotationen für das mapping zur DB, aber Sie können verstehen, was ich meine
InformationsquelleAutor der Frage Matthieu Napoli | 2011-04-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin müde, aber das scheint viel Lärm um nichts.
Verpasst die wichtige bit der Warnung:
Das ist nicht der Fall in deinem Beispiel! Hätten Sie nicht verzichtet, die Lehre von Anmerkungen, die Sie vielleicht bemerkt haben.
Des Vereins User::Haustiere ist OneToMany, nicht von [Einem|Vielen]ToOne. Ein Benutzer hat viele Haustiere.
Die inverse Assoziation ist OneToOne, aber es ist targeting auf Nutzer, die keine erbschaft.
Robin ' s Antwort sollte schon einen guten Tipp gegeben -- Sie können sich die sql-Abfragen und sehen, was Lehre eigentlich tut, um Ihre Datenbank!
Bad-for-performance-Szenario ist so etwas wie:
Nun, wenn Sie wollte Iteration über alle blauen Kragen, Lehre läuft in Schwierigkeiten. Er weiß nicht, was Klasse $Besitzer sein wird, also kann es nicht die Verwendung eines Proxys. Stattdessen werden Sie gezwungen, eifrig zu laden $Besitzer, um herauszufinden, ob es eine Katze oder ein Hund.
Dies ist nicht ein problem für OneToMany oder ManyToMany Beziehungen, da in diesem Fall, lazy loading funktioniert einwandfrei. Statt einem proxy, erhalten Sie eine PersistentCollection. Und ein PersistentCollection ist immer nur ein PersistentCollection. Es kümmert sich nicht um eigene Inhalt, bis Sie wirklich Fragen, für Sie. So lazy loading funktioniert einwandfrei.
InformationsquelleAutor der Antwort timdev
Ich glaube, du hast missverstanden, den Abschnitt des Handbuchs, Sie haben zitiert, trägt den Titel "Performance-impact", Sie sind nicht sagen, Sie Sie nicht dies tun, nur, dass es Auswirkungen auf die Leistung, wenn Sie tun. Dies macht Sinn, für lazy loading - für heterogene Sammlungen von STI-Entitäten, die Sie haben zu gehen, um die Datenbank, und laden Sie das Element aus, bevor Sie wissen, welche Klasse es sein wird, so lazy loading ist nicht möglich /nicht sinnvoll. Ich Lerne, Lehre 2 mich im moment, so dass ich verspottet, bis dein Beispiel, die folgenden Werke OK für mehr:
... und das test-Skript ....
Alle meine Katzen und Hunde laden der korrekte Typ:
Wenn du dir den generierten SQL -, werden Sie feststellen, dass, wenn die OneToMany targetEntity ist "pet", erhalten Sie SQL folgendermaßen:
Aber wenn es ist für die Katze, Sie bekommen dieses:
HTH.
InformationsquelleAutor der Antwort Robin