2014-01-22 4 views
7

In meinem Projekt habe ich mehrere haben class table inheritances wie folgt aus:Karte einen Diskriminator Spalte auf einem Feld mit Lehre 2

namespace MyProject\Model; 

/** 
* @Entity 
* @InheritanceType("JOINED") 
* @DiscriminatorColumn(name="discr", type="string") 
* @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) 
*/ 
class Person 
{ 
    // ... 
} 

/** @Entity */ 
class Employee extends Person 
{ 
    // ... 
} 

Ich habe eine Methode, die Entitäten wandelt auf den Feldern auf Arrays basieren, die öffentliche Getter haben. Das Problem hier ist, dass ich die Vererbungsinformationen in meinem Array verliere, weil der Diskriminatorwert nicht in einem Feld gespeichert ist.

Also, was ich versuchte, wurde die folgende, würde die Hoffnung Lehre automatisch $disc:

class Person 
{ 
    // can I automatically populate this field with 'person' or 'employee'? 
    protected $discr; 

    public function getDiscr() { return $this->discr; } 
    public function setDiscr($disc) { $this->discr; } 

    // ... 
} 

Gibt es eine Möglichkeit, diese Arbeit in der Lehre zu machen? Oder müsste ich die Klassenmetadaten in meiner Entity-to-Array-Methode lesen?

+1

Mögliche Duplikat (http://stackoverflow.com/ Fragen/4450381/Can-i-Access-Diskriminator-Feld-von-PHP-in-Lehre2) – Maks3w

Antwort

16

Leider gibt es keine dokumentierte Möglichkeit, die discr-Spalte einer Entität zuzuordnen. Das liegt daran, dass die Discr-Spalte wirklich Teil der Datenbank und nicht der Entität ist.

Es ist jedoch durchaus üblich, den discr-Wert direkt in Ihre Klassendefinition einzugeben. Es wird sich nicht ändern und Sie werden immer die gleiche Klasse für den gleichen Wert bekommen.

class Person 
{ 
    protected $discr = 'person'; 

class Employee extends Person 
{ 
    protected $discr = 'employee'; 
+0

Ja, ich hatte Angst, ich müsste so etwas. Vielen Dank. – sroes

+0

Große Antwort, einfache aber effektive Lösung. – Oli

1

können Sie die folgende Lösung verwenden:

`$`$metadata = \Doctrine\ORM\Mapping\ClassMetadata((string)$entityName); 
print_r($metadata->discriminatorValue);` 
3

Hier ist ein kleines Beispiel von dem, was ich in einem meiner ZF2 Projekte (mit Lehre MongoDB ODM) haben:

// an instance of your entity 
$entity = ...; 

/** @var \Doctrine\ODM\MongoDB\DocumentManager $documentManager */ 
$documentManager = $serviceManager->get('DocumentManager'); 

/** @var \Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactory $factory */ 
$factory = $documentManager->getMetadataFactory() 

/** @var \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $metadata */ 
$metadata = $factory->getMetadataFor(get_class($object)); 

if ($metadata->hasDiscriminator()) { 
    // assuming $data is result of the previous extraction 
    $data[$metadata->discriminatorField] = $metadata->discriminatorValue; 
} 

Was ich getan habe, ist, dass ich eine benutzerdefinierte Schnittstelle implementiert habe DiscriminatorAwareInterface und ich nur die Prüfungen auf Klassen anwenden, die es implementieren (in Ihrem Fall wäre es die Klasse, die alle "dis Kriminelle "Klassen erweitern.

Als Folge ich mit dem Code am Ende, das wie folgt aussieht:

// add value of the discrinimator field to entities that support it 
if ($object instanceof DiscriminatorAwareInterface) { 
    /** @var \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $metadata */ 
    $metadata = $factory->getMetadataFor(get_class($object)); 

    if ($metadata->hasDiscriminator()) { 
     $data[$metadata->discriminatorField] = $metadata->discriminatorValue; 
    } 
} 

Ich bin mir ziemlich sicher, es wird das gleiche sein, wenn Sie die Standard-ORM verwenden, es sei denn statt einem Dokumentenmanager haben Sie Entitätsmanager.

2

Wir waren gerade dieses Problem und löste es, ohne den Unterscheider als echtes Mitglied der Definition: [? Kann ich Scheider Feld zugreifen php in Doctrine2]

abstract class MyEntity { 
    const TYPE_FOO = 'foo'; 
    const TYPE_BAR = 'bar'; 
    const TYPE_BUZ = 'buz'; 
    ... 
    /** 
    * @return string 
    */ 
    public function getMyDiscriminator() 
    { 
     $myDiscriminator = null; 
     switch (get_class($this)) { 
      case MyEntityFoo::class: 
       $myDiscriminator = self::TYPE_FOO; 
       break; 
      case MyEntityBar::class: 
       $myDiscriminator = self::TYPE_BAR; 
       break; 
      case MyEntityBuz::class: 
       $myDiscriminator = self::TYPE_BUZ; 
       break; 
     } 
     return $myDiscriminator; 
    } 
    ... 
} 

class MyEntityFoo extends MyEntity {} 

class MyEntityBar extends MyEntity {} 

class MyEntityBuz extends MyEntity {} 
Verwandte Themen