2011-10-26 10 views
9

と多くの多くは、私は3つのテーブルドクトリン2 3つのエンティティと参加表

People 
- id -pk 
- name 

Roles 
- id -pk 
- roleName 

Events 
- id -pk 
- title 

を持っており、結合表

event_performers 
- event_id -pk 
- role_id -pk 
- people_id -pk 

イベントには多くの役割を持っています。 役割は個人によって実行されます。 役割は多くのイベントに関連付けられています。 人は多くのロールを実行できます。

私はイベントを受け取ると、そのイベントに関連するロールのコレクションにアクセスでき、ロールからロールを実行することができます。

Doctrine 2でこれをどのようにマッピングするのか分かりません。

答えて

18

約1週間前に同じ問題が発生しました。私はDoctrine IRCチャンネルのユーザーに最良の解決策(または最も一般的に練習されているもの)を投票しました。これは完了です:

@ManyToOne、$ event、$ person、$ roleを使って3つのプロパティをマップしたEventsPeopleRolesのような名前の新しいエンティティを作成します。あなたはその後持っ

/** 
* @OneToMany(targetEntity="EventsPeopleRoles", mappedBy="event") 
*/ 
private $eventsPeopleRoles; 

各アソシエーションはこれに類似マップされるべきである:

/** 
* @ManyToOne(targetEntity="Events", inversedBy="eventsPeopleRoles") 
* @JoinColumn(name="event_id", referencedColumnName="id", nullable=false) 
*/ 
private $event; 

を3つのに関連するエンティティのそれぞれにおいて、コードのような関連の逆側「結合エンティティ」に$ idプロパティを追加するか、hereのようにコンポジット主キーを使用して、エンティティクラス定義に一意の制約注釈を追加するかを選択できます。複合外部キーはDoctrine 2.1からのみサポートされています。

私はこのソリューションについて懐疑的でした。なぜなら、私は結合の目的のためだけにエンティティを作成するという考えが嫌いです。 ORMの設計原則とは対照的に、少なくとも不正行為のように思えます。しかし、私はこれが(少なくとも今のところは)教義の専門家の間で受け入れられた解決策であると確信しています。

+0

返信いただきありがとうございます。私はこれを試し、私がどのように乗っているかをお知らせします。 –

+0

パーフェクト。ありがとう! –

+0

これは完全に私のために働くようだ... 共有ありがとう! – jfgrissom

3

@ cantera25の解決策は正しいです。

私はそれに考えを加えたいと思います。

通常、結合エンティティが3つ以上のエンティティを結合する場合、それは情報アーキテクチャで非常に重要な役割を果たしていることを示しており、名前を変更する必要があります。

たとえば、私が乗馬厩舎のために取り組んでいるアプリケーションには、Bookingエンティティがあります。

Bookingには少なくとも1つのRiderがあり、その予約にはHorseが搭乗しています。

私は当初、BookingRiderHorseというエンティティを設計しました。これらの3つを一緒に結合しました。

言うまでもなく、私はコードを再訪したときにそれがかなり乱雑で理解しにくかったでしょう。

以前のBookingエンティティの名前をRideに変更し、BookingRiderHorseエンティティの名前をBookingに変更しました。

ビジネスロジックでは、Bookingsが作成され、既存のRide,Horse、およびRiderレコードを持つ必要があります。各Bookingは、1つだけHorseRiderを持ちますが、それぞれRideは、多くの場合、Bookingsを持つことができます。

面白い名前の結合表を使用するのと同じですが、はるかに分かりやすく、結合の仕組みを考える必要がなくビジネスロジックを処理できます。私はと

5

は、場合、誰かが私はちょうど@canteraことで、この偉大な答えにいくつかの注釈を追加します、初心者の通りです:3つのエンティティのそれぞれにおいて

、あなただけの、彼が提案したコードを追加する必要があります"ManyToOne"と "JoinColumn"の前に "ORM \"を含めなければならないことに注意してください。また、私はちょうどかのうな限り明確にするために、「@var」の注釈を追加しました:自分のエンティティ名=「eventsPeopleRoles」で

、3つのエンティティのそれぞれの参照を追加します。

/** 
* @var Events $event 
* 
* @ORM\ManyToOne(targetEntity="Events", inversedBy="eventsPeopleRoles") 
* @ORM\JoinColumn(name="event_id", referencedColumnName="id", nullable=false) 
*/ 
private $event; 

/** 
* @var Events $people 
* 
* @ORM\ManyToOne(targetEntity="Person", inversedBy="eventsPeopleRoles") 
* @ORM\JoinColumn(name="person_id", referencedColumnName="id", nullable=false) 
*/ 
private $people; 

/** 
* @var Role $role 
* 
* @ORM\ManyToOne(targetEntity="Role", inversedBy="eventsPeopleRoles") 
* @ORM\JoinColumn(name="role_id", referencedColumnName="id", nullable=false) 
*/ 
private $role; 

自分のエンティティ名であなたのEntitで= "イベント" 自分のエンティティ名= "人物"

/** 
* @var ArrayCollection $eventsPeopleRoles 
* 
* @ORM\OneToMany(targetEntity="EventsPeopleRoles", mappedBy="people") 
*/ 
private $eventsPeopleRoles; 

/** 
* @var ArrayCollection $eventsPeopleRoles 
* 
* @ORM\OneToMany(targetEntity="EventsPeopleRoles", mappedBy="event") 
*/ 
private $eventsPeopleRoles; 

y name = "Role"

/** 
* @var ArrayCollection $eventsPeopleRoles 
* 
* @ORM\OneToMany(targetEntity="EventsPeopleRoles", mappedBy="roles") 
*/ 
private $eventsPeopleRoles; 
+0

eventsPeopleRolesエンティティクラス内で間違えました。プライベート$イベントの代わりに。最後に、それはプライベート$ロールです。 – kabrice

+0

エドガーに感謝、私は私の答えを修正しました。 – aleph