Map a discriminator column to a field with Doctrine 2

前端 未结 4 1776
慢半拍i
慢半拍i 2020-12-09 05:41

In my project I have several class table inheritances like this:

namespace MyProject\\Model;

/**
 * @Entity
 * @InheritanceType(\"JOINED\")
 * @Discriminat         


        
相关标签:
4条回答
  • 2020-12-09 06:05

    You can use the following solution:

    `$`$metadata = \Doctrine\ORM\Mapping\ClassMetadata((string)$entityName);
    print_r($metadata->discriminatorValue);`
    
    0 讨论(0)
  • 2020-12-09 06:09

    Sadly, there is no documented way to map the discr column to an entity. That's because the discr column is really part of the database and not the entity.

    However, it's quite common to just put the discr value directly in your class definition. It's not going to change and you will always get the same class for the same value anyways.

    class Person
    {
        protected $discr = 'person';
    
    class Employee extends Person
    {
        protected $discr = 'employee';
    
    0 讨论(0)
  • 2020-12-09 06:18

    Here's a small example of what I have in one of my ZF2 projects (using Doctrine MongoDB ODM):

    // 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;
    }
    

    What I have done is I've implemented a custom interface DiscriminatorAwareInterface and I only apply the checks to classes that implement it (in your case it would be the class that all "discriminated" classes extend.

    As a result I end up with code that looks like this:

    // 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;
        }
    }
    

    I'm pretty sure it will be the same if you use the standard ORM, except instead of a document manager you will have entity manager.

    0 讨论(0)
  • 2020-12-09 06:25

    Just got this problem and solved it without defining the discriminator as a real member:

    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 {}
    
    0 讨论(0)
提交回复
热议问题