如何在Doctrine2中为类表继承指定外键列?

时间:2011-07-21 13:35:46

标签: php sql inheritance doctrine-orm class-table-inheritance

如何在Doctrine 2中指定用于类表继承的外键关系的列?例如,请使用以下两个类:

/**
 * @Entity
 * @InhertanceType("JOINED")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap("person" = "Person", "employee" = "Employee")
 */
class Person
{
    /** @Id */
    public $id;

    /** @Column(type="string") */
    public $ssn;
}

/** @Entity */
class Employee
{
    /** @Column(type="decimal") */
    public $salary;
}

有了这个,Doctrine期待一个表结构:

CREATE TABLE `person` (
    `id` INT(11) NOT NULL auto_increment,
    `ssn` VARCHAR(255) default NULL,
    PRIMARY_KEY(`id`)
)

CREATE TABLE `employee` (
    `person_id` INT(11) NOT NULL,
    `salary` DECIMAL(10,2) default NULL,
    PRIMARY_KEY(`person_id`)
)
ALTER TABLE `employee`
    ADD CONSTRAINT `person_fk` FOREIGN KEY (`person_id`)
        REFERENCES `person` (`id`) ON DELETE CASCADE

外键employee.person_id指向person.id。但是,如何告诉Doctrine使用哪些列?我假设person.id引用来自@Id类上的Person注释,但如果我想将FK创建为person.ssn,那么(可以想象,因为SSN)自然是独一无二的。)

如果我的遗留数据库中employee.person_id被称为employee.p_id,那该怎么办?

1 个答案:

答案 0 :(得分:3)

首先,您缺少Employee类定义中的“extends Person”。

据我所知,当你进行这种类型的继承时,doctrine使用主类中的主键来连接所有其他表,它是预期的行为。

当您进行查询时,doctrine会将所有子表连接到父级,然后根据鉴别器映射进行水合。考虑到这一点,主键是自动增量ID还是唯一字段无关紧要。如果在父类中定义了ssn,则可以在所有子类中进行搜索。

这里有几个提示。如果需要,可以删除自动id并使用ssn作为主键,然后doctrine期望所有子表都在其中定义相同的字段。为了性能,最好还是使用整数而不是255字符串来进行连接。

如果你想保留自动id,你可能想要为父类添加一个唯一索引,这样如果你按该字段访问类,你就不会让性能降低。

如果您希望将类名称作为某些内容而将表名称作为其他名称,请使用此

/** @Id @Column(name="p_id") */
public $id;

但请记住,作为继承一部分的所有表都应该使用该名称。

此外,我通常使用doctrine来映射现有数据库并扩展它(迁移到doctrine),如果我添加一个新功能并且模型需要,我自己创建映射和表,记住Doctrines如何继承有效。但是如果您有现有的表可以使用继承建模,那么可能会遇到麻烦,也许需要修改现有的表。

希望这有帮助。