1

ここで指摘されているように: Doctrine 2.1 - エンティティを複数のテーブルにマップするDoctrine2 では、1 つのオブジェクトを複数のテーブルにマッピングすることはできません。

現在、次のような Mysql db セットアップがあります。

base_entity: id, some_basic_data_columns
state: id, state, entity_id (FK to base_entity.id), start_time, end_time, ...

entity_one: id (FK to base_entity.id), some_specific_data
entity_two: id (FK to base_entity.id), some_specific_data
and so on...

ある意味、entity_x は base_entity を「拡張」しており、これらのエンティティはすべて複数の状態を持つことができます。適切な外部キーを取得するには、個別の状態テーブルを用意するか (構造的に同じになるため、これはしたくありません)、このようにする必要があります。

ベース エンティティ自体は役に立たず、id を id フィールドだけに煮詰めて、各子エンティティを複数の状態に結合できるようにすることもできます。

BaseEntity クラスは必要ありませんが、子エンティティごとに getStates() メソッドが必要です。もちろん、私は実際に抽象エンティティ クラスを持っているかもしれませんが、具体的なエンティティはそれを拡張し、他の 1 対 1 の関係をマップするようにマップする場合のようにプロパティとして持つことはありません。

Doctrine では EntityOne を entity_one と base_entity テーブルの両方にマップすることができないため、次のように質問する必要があります。

  1. これはデザインが悪いのでしょうか?これをエレガントに解決する他の方法を見落としていますか? 他のDMBSには継承があることは知っていますが、たとえばPostgreSqlでは、子に物理的なbase_entityが存在しない場合、base_entityに参加して状態を維持することはできません。

  2. コード側で次のようなことができます。

    class EntityOne {
        // baseEntity as a property
        private $_baseEntity;
    
        // private getter for the base table
        private getBaseEntity();
    
        // and getters like this for properties in the base table
        public getStates(){ 
             return $this->getBaseEntity()->getStates();
        }
    } 
    

    このようにして、エンティティは外部に対して単一のエンティティ (ベースと子から結合されていない) のように動作しますが、別の BaseEntity クラスと、それを他のエンティティ クラスに接続するためのすべての構成情報を記述する必要があります。

基本的に、私が求めているのは、これはDbの設計上の問題であり、最初から完全に間違っていたのですか(もしそうなら、これが「最良の」アプローチです)、それともコードの問題ですか?コードでそれを回避します(もしそうなら、2.での私のアプローチは大丈夫ですか、これに対処するためのより良い方法はありますか)、複数のテーブルマッピングを可能にするORMはありますか?

よろしくお願いします。

4

1 に答える 1

2

Class Table Inheritance (これについては Doctrine のドキュメントを参照) を使用して、BaseEntity エンティティ クラスを定義し、それを拡張する EntityOne と EntityTwo を作成できます。BaseEntity クラスと State エンティティ クラスの間の関係を 1 対多の関連付けとして定義できます。必要な getState() メソッドを BaseEntity クラスに提供することで、必要なことが理解できれば。

このようなもの:

/**
 * @Entity
 * @Table(name="base_entity")
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="entity_type", type="string")
 * @DiscriminatorMap({"entity_one"="EntityOne", "entity_two"="EntityTwo"})
 */
class BaseEntity {

    /**
     * @Id
     * @Column(type="integer")
     */
    protected $id;

    /**
     * @OneToMany(targetEntity="State", mappedBy="entity)
     **/
    protected $states;

    public function getStates() {
        return $this->states;
    }

    ...
}

/**
 * @Entity
 * @Table(name="entity_one")
 */
class EntityOne extends BaseEntity {

    ...
}

/**
 * @Entity
 * @Table(name="entity_two")
 */
class EntityTwo extends BaseEntity {

    ...
}

/**
 * @Entity
 * @Table(name="state")
 */
class State {

    /**
     * @ManyToOne(targetEntity="BaseEntity", inversedBy="states")
     * @JoinColum(name="entity_id", referencedColumnName="id")
     */
    protected $entity;

    public function getEntity() {
        return $this->entity;
    }

    ...
}
于 2012-04-20T21:16:29.340 に答える