3

Doctrine 2のクラステーブル継承との外部キー関係に使用される列を指定するにはどうすればよいですか?たとえば、次の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クラス定義に「extendsPerson」がありません。

私の知る限り、このタイプの継承を行う場合、doctrineはメインクラスの主キーを使用して他のすべてのテーブルを結合します。これは予想される動作です。

クエリを実行すると、Doctrineはすべての子テーブルを親に結合し、ディスクリミネーターマップに従ってハイドレイトします。そのことを念頭に置いて、主キーが自動的に増分IDであるか一意のフィールドであるかは問題ではありません。親クラスでssnを定義している場合は、すべてのサブクラスで検索できるようになります。

ここにいくつかのヒントがあります。必要に応じて、自動IDを削除し、ssnを主キーとして使用できます。そうすると、doctrineは、すべての子テーブルに同じフィールドが定義されていることを期待します。パフォーマンスのために、とにかく結合を行うには、255文字列の代わりに整数を使用するのが賢明かもしれません。

自動化されたIDを維持する場合は、親クラスに一意のインデックスを追加することをお勧めします。そうすれば、そのフィールドでクラスにアクセスしても、パフォーマンスが低下することはありません。

クラス名を何かにし、テーブル名を別のものにしたい場合は、これを使用します

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

ただし、継承の一部であるすべてのテーブルでその名前を使用する必要があることに注意してください。

さらに、私は通常、既存のデータベースのマッピングと拡張(Doctrineへの移行)にdoctrineを使用します。新しい機能を追加し、モデルで必要な場合は、Doctrineの継承がどのように機能するかを念頭に置いてマッピングとテーブルを自分で作成します。ただし、継承を使用してモデル化できると思われる既存のテーブルがある場合は、問題が発生する可能性があり、既存のテーブルを変更する必要があるかもしれません。

お役に立てれば。

于 2011-10-12T18:29:43.303 に答える