3

如何使用 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怎么办?

4

1 回答 1

3

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

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

当您进行查询时,学说会将所有子表连接到父表,然后根据鉴别器映射进行水合。考虑到这一点,您的主键是自动递增的 id 还是唯一字段都没有关系。如果您在父类中定义了 ssn,它将可用于在您的所有子类中进行搜索。

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

如果您想保持自动 id,您可能需要向父类添加唯一索引,这样如果您通过该字段访问类,则不会降低性能。

如果你想让类名是什么而表名是别的东西,使用这个

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

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

此外,我通常使用学说来映射现有数据库并对其进行扩展(迁移到学说),如果我要添加新功能并且模型需要这样做,我会自己创建映射和表,同时牢记学说继承的工作原理。但是,如果您有认为可以使用继承建模的现有表,则可能会遇到一些麻烦,并且可能需要修改现有表。

希望这可以帮助。

于 2011-10-12T18:29:43.303 回答