ZF2 + Doctrine 2 - 具有类表继承的子级别鉴别器

时间:2017-07-10 14:56:27

标签: php doctrine-orm zend-framework2 class-table-inheritance

关于ZF2与Doctrine 2和使用Discriminators的关于SO和网络的很多问题是:你怎么不在父实体上声明所有子实体?特别是当你有多个模块时?

答案简短:不要声明discriminatorMap。 Doctrine会为你处理它。

答案越长越好。

1 个答案:

答案 0 :(得分:1)

一篇关于如何能够在子实体上声明您的子实体的热门文章,而不是父实体is this one

但是,学说2自写作以来有所改变,例如, AnnotationWriter不再存在。

然而,正如我在问题中提到的那样,有一种更简单的方法:什么也不做。

现在使用“Class Table Inheritance”方法(而不是“单表继承”)使用鉴别器是为了不去除判别器映射! (不确定这是否也适用于STI ...)

我发现了一张旧票on Github,它解释了与这个答案相同的问题,许多人仍然拥有这个问题,宣称对父母没有任何意义。阅读完之后,我仔细研究了代码并重新阅读了文档。

此外,如果您在阅读文档时非常小心,它会说这是可能的,不是说它。

引用:

  

注意事项:

     

必须在作为映射实体层次结构一部分的最顶层上指定@InheritanceType,@ DisciminatorColumn和@DiscriminatorMap。

     

@DiscriminatorMap指定鉴别器列的哪些值将行标识为哪种类型。在上面的情况中,值“person”将行标识为Person类型,“employee”将行标识为Employee类型。

     

如果类包含在与应用鉴别器映射的实体类相同的命名空间中,则鉴别器映射中的类的名称不需要完全限定。

     

如果没有提供鉴别器映射,则会自动生成映射。自动生成的鉴别器映射包含每个类的小写短名称作为键。

当然,上面的文档确实明确声明如果没有提供地图将会生成。虽然与第一个注意事项相矛盾,但必须在层次结构中最顶层的类上提供@DiscriminatorMap

所以,如果你要在几个模块中扩展你的课程(因为我认为这就是为什么你会读这个),不要声明一个鉴别器地图!

我将在下面给你一个例子:

<?php
namespace My\Namespace\Entity;

/**
 * @Entity
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="discr", type="string")
 * // NOTE: No @DiscriminatorMap!!!
 */
class Person
{
    // ...
}


<?php
namespace My\Other\Namespace\Entity;

/** @Entity */
class Employee extends \My\Namespace\Entity\Person
{
    // ...
}

当您使用doctrine CLI命令检查实体时,您会发现这是正确的。

此外,使用实体检查命令检查它是否完全有效:

./vendor/bin/doctrine-module orm:mapping:describe “\My\Namespace\Entity\Person”

该命令的响应顶部附近将是以下行:

| Discriminator map | {“person”:”My\\Namespace\\Entity\\Person”,”employee”:”My\\Other\\Namespace\\Entity\\Employee”}