4

Doctrine 2 Inheritance Mapping with Associationを読みAnimalましたが、それ自体がエンティティである必要がある場合は、オプションリストを作成する場合などです。

この場合、aのDiscriminator列Petは、の種列にありanimal tableます。

ペットデータベーススキーマ

したがって、クラスは次のようになります。

class Animal
{
    $id;
    $species;
}

/**
 * @Table(name="animal")
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="species", type="string")
 * @DiscriminatorMap({"dog" = "Dog", "cat" = "Cat"})
 */
abstract class Pet
{
    $id
    $species;
}

class Dog extends Pet { }

class Cat extends Pet { }

class Owner 
{
    /**
     * @OneToMany(targetEntity="Pet")
     */
    $pets
}

いくつかの問題があります。

  1. テーブルにはへの外部キーがありanimalませんowner。したがって、 $pets協会は機能しません。

  2. AnimalそしてPet多かれ少なかれ同じことです。誰かがそれらの変更で何かを変更した場合Animal、どのPetサブクラスにも反映されません。

最初の問題に対する可能な解決策は、と呼ばれる追加のテーブルを用意するpetことですが、識別子の列がまだanimalテーブルにあり、列を複製するとpet正規化が失敗するため、関連付けにはまだ問題があります。

ここに画像の説明を入力してください

4

1 に答える 1

3

あなたの問題を完全に理解しているかどうかはわかりませんが、試してみます:

  • APetは であるため、クラス階層で明示的にするAnimalことは理にかなっています。抽象クラスは具象クラスをサブクラス化できることに注意してください。このようにして、 an 、 aまたは aをインスタンス化することはできますが、 ;をインスタンス化することはできません。PetAnimalAnimalDogCatPet
  • ルートAnimalクラスは独自の識別子値を持つことができ、Doctrine で永続化することができます。Dog次に、または 、CatさらにはジェネリックAnimal;を作成して永続化できます。
  • Animalその所有者への参照が必要です。
  • Owner1 対多の関係になりましたAnimal
  • species列は識別子であり、ドメイン モデルに何の価値も追加しませ(クラス名は、何をAnimal扱っているかを示します)。そのため、このプロパティを削除することをお勧めします。

Pet最後に、クラスは本当に必要ですか? Pet が特定のものを持たない場合Animal(つまり、クラスが空である場合) は、おそらくクラス階層から削除する必要があります。

class Owner {
    /**
     * @OneToMany(targetEntity="Animal")
     */
    protected $animals;
}

/**
 * @Table(name="animal")
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="species", type="string")
 * @DiscriminatorMap({"animal" = "Animal", "dog" = "Dog", "cat" = "Cat"})
 */
class Animal {
    /** @Id @Column(type="integer") @GeneratedValue */
    protected $id;

    /** @ManyToOne(targetEntity="Owner") */
    protected $owner;
}

abstract class Pet extends Animal {
    // Do you really need this class?
}

class Dog extends Pet {
    // ...
}

class Cat extends Pet {
    // ...
}

データベース構造について、次の変更を提案します。

  • &owner_idからテーブルに移動します。DogCatAnimal
  • &テーブルanimal_idから削除します。テーブルと値を共有します ( 1 対 1 )。DogCatidAnimal
于 2011-11-27T23:44:46.693 に答える