ZF2 + Doctrine 2 - 具有 Class Table 继承的子级鉴别器

ZF2 + Doctrine 2 - Child-level discriminators with Class Table Inheritance

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

简短的回答是:不要声明discriminatorMap。 Doctrine 会为您处理。

下面是较长的答案。

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

但是,Doctrine 2 自编写以来发生了一些变化,例如AnnotationWriter 不再存在。

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

现在使用“Class Table Inheritance”方法(与“单一 Table 继承”相反)来使用鉴别器就是不声明鉴别器映射! (不确定这是否也适用于 STI……)

我找到了一张旧票 on Github,它解释了与此答案相同的问题,而且很多人仍然持有,在 parent 上声明没有任何意义。通读完之后,我仔细研究了代码和 re-read 文档。

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

引用:

Things to note:

The @InheritanceType, @DiscriminatorColumn and @DiscriminatorMap must be specified on the topmost class that is part of the mapped entity hierarchy.

The @DiscriminatorMap specifies which values of the discriminator column identify a row as being of which type. In the case above a value of “person” identifies a row as being of type Person and “employee” identifies a row as being of type Employee.

The names of the classes in the discriminator map do not need to be fully qualified if the classes are contained in the same namespace as the entity class on which the discriminator map is applied.

If no discriminator map is provided, then the map is generated automatically. The automatically generated discriminator map contains the lowercase short name of each class as key.

当然,上面的文档确实明确指出如果提供 none,将生成 地图 。尽管它矛盾需要注意的第一件事,即@DiscriminatorMap必须提供在最顶层class层次结构。

因此,如果您要将 classes 扩展到多个模块(我假设这就是您阅读本文的原因),请不要声明鉴别器映射!

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

<?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”}