ZF2 + Doctrine 2 - 具有类表继承的子级鉴别器
关于 ZF2 和 Doctrine 2 以及使用鉴别器,SO 和网络上的很多问题是:如何不在父实体上声明所有子实体?尤其是当您有多个模块时?
Much asked on SO and around the web with regards to ZF2 with Doctrine 2 and using Discriminators is: how do you not declare all child Entities on the parent Entity? Especially when you have multiple modules?
简短的回答是:不要声明 discriminatorMap
.Doctrine 会为您处理.
The short answer is: do not declare a discriminatorMap
. Doctrine will handle it for you.
较长的答案如下.
推荐答案
一篇关于如何能够声明子实体的流行文章,在子实体上,而不是在父实体上,就是这个.
A popular article on how to be able to declare your child Entities, on the children Entities, instead of the parent, is this one.
然而,Doctrine 2 自编写以来发生了一些变化,例如AnnotationWriter
不再存在.
However, Doctrine 2 has changed somewhat since it was written, e.g. the AnnotationWriter
no longer exists.
但是,正如我在问题中提到的那样,还有一种更简单的方法:什么都不做.
There, however, is a simpler way, as I mentioned in the question: do nothing.
现在使用类表继承"方法(与单表继承"相对)是不声明鉴别器映射!(不确定这是否也适用于 STI ……)
To now use Discriminators using the "Class Table Inheritance" method (as opposed to "Single Table Inheritance") is to NOT DECLARE a Discriminator Map! (Not sure if this will also work for STI…)
我在 Github 上找到了一张旧票 在 Github 上,它解释了与此答案相同的问题并且许多人仍然拥有,向父母声明是没有意义的.通读之后,我开始深入研究代码并仔细阅读文档.
I found an old ticket on Github that explains the same issue as this answer and which many people still have, that declaring on the parent makes no sense. After reading through that, I dove into the code and re-read the docs, carefully.
此外,如果您在阅读文档时非常小心,它会说这是可能的,但不要说出来.
Also, if you’re reeeeaaally careful when reading the docs, it says this is possible, by not saying it.
引用:
注意事项:
@InheritanceType、@DiscriminatorColumn 和 @DiscriminatorMap 必须在作为映射实体层次结构一部分的最顶层类中指定.
@DiscriminatorMap 指定鉴别器列的哪些值将行标识为哪种类型.在上面的例子中,person"的值将一行标识为 Person 类型,employee"将一行标识为 Employee 类型.
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.
当然,上面的文档确实明确指出,如果没有提供地图,将生成.尽管它矛盾首先要注意,即@DiscriminatorMap
必须提供在层次结构中的最顶层.
Of course, the above piece of documentation does explicitly state that a map would be generated if none was provided. Though it contradicts the first thing to note, which is that the @DiscriminatorMap
must be provided on the topmost class in the hierarchy.
因此,如果您要将类扩展到多个模块(我认为这就是您阅读本文的原因),请不要声明鉴别器映射!
So, if you were to stretch your classes across several modules (as I assume that’s why you would be reading this), do not declare a discriminator map!
我会在下面给你一个例子:
I’ll leave you with an example below:
<?php
namespace MyNamespaceEntity;
/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* // NOTE: No @DiscriminatorMap!!!
*/
class Person
{
// ...
}
<?php
namespace MyOtherNamespaceEntity;
/** @Entity */
class Employee extends MyNamespaceEntityPerson
{
// ...
}
当您使用 Dotct CLI 命令检查您的实体时,您会发现这是正确的.
When you use the doctrine CLI command to check your entities, you’ll find this is correct.
另外,使用实体检查命令检查它是否完全正常工作:
Also, check that it fully works by using the entity checking command:
./vendor/bin/doctrine-module orm:mapping:describe "MyNamespaceEntityPerson"
在该命令响应的顶部附近将是这一行:
Near the top of the response of that command will be this line:
| Discriminator map | {"person":"My\Namespace\Entity\Person","employee":"My\Other\Namespace\Entity\Employee"}
相关文章