0

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

简短的回答是:不要声明一个discriminatorMap. 教义会为你处理它。

更长的答案如下。

4

1 回答 1

1

一篇关于如何在子实体而不是父实体上声明您的子实体的热门文章是这篇文章

然而,教义 2 自编写以来已经发生了一些变化,例如AnnotationWriter不再存在。

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

现在使用“<a href="http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html#class-table-inheritance" rel= “nofollow noreferrer">类表继承”方法(相对于“单表继承”)是不声明一个鉴别器映射!(不确定这是否也适用于 STI……)

我在 Github 上找到了一张旧票,它解释了与这个答案相同的问题,而且很多人仍然有这个问题,在父级上声明是没有意义的。阅读完之后,我仔细研究了代码并重新阅读了文档。

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

报价:

注意事项:

@InheritanceType、@DiscriminatorColumn 和 @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
{
    // ...
}

当您使用理论 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”}
于 2017-07-10T14:56:26.927 回答