我有两节课,其中一节课在第二节课之前已经完全开发。当我开始开发第二个时,因为它基本相同,但具有额外的功能,我在 PHP 中扩展了该类。
让我们称父类 ClassA 和子类 ClassB (为简洁起见,省略了 getter/setter):
class ClassA
{
protected $label;
protected $name;
}
class ClassB extends ClassA
{
protected $extraField;
}
然而,当我来映射它时,我遇到了问题。我不需要也不想要继承映射,因为我不想要多态查询;这两个类都用于站点的不同部分,我不想在查询 ClassA 时返回 ClassB 的实例,而只想直接返回 ClassA 的实例。
我通过从 ClassB 的映射中排除 ClassA 的属性来使映射工作(否则它抱怨字段重复):
类A.dcm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="ClassA" table="a">
<id name="id" type="integer" column="id">
<generator strategy="AUTO" />
</id>
<field name="label" type="string" nullable="true"/>
<field name="name" type="text" nullable="true"/>
</entity>
</doctrine-mapping>
ClassB.dcm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="ClassB" table="b">
<field name="extraField" type="string" nullable="true"/>
</entity>
</doctrine-mapping>
这会正确生成包含所有必填字段的数据库表。但是,当查询它时:
$em->createQuery('SELECT b FROM ClassB')->getResult();
然后我得到一个异常抛出,因为 Doctrine 正在通过尝试巧妙地处理继承来生成这个 MySQL 查询,即使我没有映射它:
SELECT c0_.label AS label0, c0_.name AS name1, c0_.id AS id2, c1_.extraField AS extraField3 FROM b c1_
正如您所看到的,它试图通过为其指定别名来从 A 表中获取列,而它应该做的只是从 B 表中获取并且它抱怨第一列不存在。
有没有实现我想要的而不必使用单表继承或类表继承(因为我不想要多态查询)或创建额外的类(映射的超类需要)?
我将 Doctrine 2.3.3(最新版本)与 MySQL 和 PHP 5.3 一起使用。