php - 将子类映射为其扩展父类

标签 php oop orm doctrine-orm discriminator

我创建了以下抽象类,它使用 single table inheritance并在 DiscriminatorColumn 上映射子类模型

/**
 * @Entity
 * @Table(name="entity")
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="model", type="string")
 * @DiscriminatorMap({
 *      "green" = "model\GreenEntity",
 *      "blue"  = "model\BlueEntity"
 * })
 */
abstract class AbstractEntity
{
    /** @Id @Column(type="string") */
    protected $entity_id;
}

假设我通过一些类扩展了抽象类 AbstractEntity:

class GreenEntity extends AbstractEntity {}
class BlueEntity extends AbstractEntity {}

并通过更多的子类扩展它们

class GreenEntityChildOne extends GreenEntity {}
class GreenEntityChildTwo extends GreenEntity {}
class BlueEntityChildOne extends BlueEntity {}
class BlueEntityChildTwo extends BlueEntity {}

现在,例如,当我实例化 GreenEntityChildOne 并将其保存到数据库时,它会抛出一个异常,表明我没有它的映射。

我想要做的是让 GreenEntityChildOne 被映射为 GreenEntity(或者更确切地说,每个类都扩展了 AbstractEntity 被映射为扩展上层抽象类的类)。

这有可能吗?

最佳答案

纯注解是不可能的

是的,您尝试实现的映射是可能的。但是,不是纯注解。重要的是 Doctrine 需要在运行时知道所有子类。如果您不想在映射父类(super class)的注释中明确声明它们,则需要动态提供它们。

救援学说事件系统

dynamic mapping with Doctrine 上有一篇很棒的博文,它解释了如何使用 Doctrine 事件监听器以编程方式更改加载的 ClassMetadata。 要动态地将子类添加到鉴别器映射,您可以实现一个 Doctrine 事件监听器,如下所示:

class DynamicDiscriminatorMapSubscriber implements EventSubscriber
{
    public function getSubscribedEvents()
    {
        return array(Events::loadClassMetadata);
    }

    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
    {
        $metadata = $eventArgs->getClassMetadata();
        $metadata->addDiscriminatorMapClass("GreenEntityChildOne", GreenEntityChildOne::class);
    }
}

注册您的订阅者

现在你只需要向 Doctrine 注册事件订阅者。理想情况下,您可以根据您的配置将要添加的类注入(inject)事件订阅者。

// create dynamic subscriber based on your config which contains the classes to be mapped
$subscriber = new DynamicDiscriminatorMapSubscriber($config);
$entityManager->getEventManager()->addEventSubscriber($subscriber);

进一步阅读

另外,看看 PHP mapping section在教义手册和更多信息API docs对于 ClassMetadataBuilder

关于php - 将子类映射为其扩展父类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32603224/

相关文章:

php - MySQL - 如何使用(LEFT)JOIN 通过一个表将两个表连接在一起?

oop - 告诉,不要问和单一职责——在类里面用数据做新的事情

Django ORM 注释 : Most common group of user queryset

java - JPQL 中有这样的 CASE 表达式吗?

symfony - 未定义索引 : inverseJoinColumns while trying to define ManyToMany relationship between two entities

php - 将类传递给set_error_handler

php - 在 Linux 中使用 PHP 创建 Word 文档

PHP MySQL 检查ID是否存在

Java 接口(interface)和对象

java - 组合具有不同字段的子类以提高效率?