【发布时间】:2017-07-10 14:56:26
【问题描述】:
关于 ZF2 with Doctrine 2 和使用 Discriminators 在 SO 和网络上的很多问题是:您如何不在父实体上声明所有子实体?尤其是当您有多个模块时?
简短的回答是:不要声明discriminatorMap。 Doctrine 会为您处理。
更长的答案如下。
【问题讨论】:
标签: php doctrine-orm zend-framework2 class-table-inheritance
关于 ZF2 with Doctrine 2 和使用 Discriminators 在 SO 和网络上的很多问题是:您如何不在父实体上声明所有子实体?尤其是当您有多个模块时?
简短的回答是:不要声明discriminatorMap。 Doctrine 会为您处理。
更长的答案如下。
【问题讨论】:
标签: php doctrine-orm zend-framework2 class-table-inheritance
一篇关于如何在子实体而不是父实体上声明子实体的热门文章is this one。
然而,《教义 2》自编写以来发生了一些变化,例如AnnotationWriter 不再存在。
但是,正如我在问题中提到的那样,有一种更简单的方法:什么都不做。
现在使用“Class Table Inheritance”方法(而不是“单表继承”)使用鉴别器就是不声明鉴别器映射! (不确定这是否也适用于 STI……)
我找到了一张旧票 on 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”}
【讨论】: