在《 Doctrine 2 ORM》中,我有一个抽象的“通信”实体,该实体使用SINGLE_TABLE继承来确定它是哪种通信类型:
Communication.orm.yaml:
App\Entity\Communication:
type: entity
table: communication
inheritanceType: SINGLE_TABLE
discriminatorColumn:
name: mode
type: string
discriminatorMap:
push: App\Entity\Communication\Push
notice: App\Entity\Communication\Notice
email: App\Entity\Communication\Email
# ...
因此,有3种通信类型(推送,通知和电子邮件)都使用“通信”表。
每个“通讯”都是可翻译的。以前,我有3个实体包含这些翻译。这些i18n实体中的每个实体都使用相同的“ i18n_communication”表,并且与它们各自的通信类型包含双向多对一关系:
由于在Doctrine 2中具有多个使用同一表但没有表继承的实体是非法的,所以我使所有的I18n实体都扩展了一个基本的I18nCommunication类,类似于它们转换的非i18n实体:
I18nCommunication.orm.yaml:
App\Entity\I18N\Communication\I18nCommunication:
type: entity
table: i18n_communication
inheritanceType: SINGLE_TABLE
discriminatorColumn:
name: communication.mode ******
type: string
discriminatorMap:
push: App\Entity\I18N\Communication\Push
notice: App\Entity\I18N\Communication\Notice
email: App\Entity\I18N\Communication\Email
# ...
这不起作用。所有扩展I18nCommunication的实体都有一个“通讯”字段,该字段引用了它们转换的通讯实体,但是Doctrine不知道该如何处理“名称:communication.mode”行。
我的问题是:如何使用相关实体中的字段作为区分列?
我尝试使用继承类型:JOINED并从Communication扩展了I18nCommunication,因此我可以访问父级的mode字段。但是,由于Communication的继承类型为SINGLE_TABLE,所以该方法不起作用,它认为I18nCommunication应该位于通讯表中。
有没有办法做到这一点?还是我不得不将我的I18nCommunication实体合并为一个实体?
谢谢。
答案 0 :(得分:0)
这行不通。 DiscriminatorColumn在当前配置的Entity中声明。注释也是,它是“ EntityAnnotation”,而不是“ PropertyAnnotation”。
任何没有以下原因的原因:
class I18nCommunication { ... }
class Push extends I18nCommunication { ... }
class Notice extends I18nCommunication { ... }
class Email extends I18nCommunication { ... }
App\Entity\I18N\Communication\I18nCommunication:
type: entity
table: i18n_communication
inheritanceType: SINGLE_TABLE
discriminatorColumn:
name: discr
type: string
在使用Single Table Inheritance时,所有数据仍然存在。
接下来,不要声明DiscriminatorMap,Doctrine将自动为您处理。请参见上方STI链接下的最后一个项目符号:
如果未提供区分图,则该图将自动生成。自动生成的鉴别符将每个类的小写缩写名映射为键。
还要在问题标题中提问:
使用联接表中的字段作为区分符
这永远不会发生,很简单,因为:联接表将是唯一知道该数据的表。兄弟姐妹将无法使用它,因此他们永远都不知道自己是其他事物的一部分。
因此,也永远不会将其构建为可用的东西。
作为类别注释的鉴别符必须始终出现在被鉴别批次的“父”上。您的情况是:I18nCommunication。