1

次の点で問題があります...電話番号の表があります。ユーザーと会社で同じテーブルを使いたい。ユーザーは複数の電話番号と会社を持つこともできます。したがって、2 つの異なる結合テーブルとの 1 対多の一方向の関係が必要です。1 つは電話番号をユーザーにリンクするもので、もう 1 つは電話番号を企業にリンクするものです。これは、doctrine2 マニュアルの第 5.9 章に続く解決策です: (クリック)

私の users エンティティは次のコードを保持しています:

/** @ORM\ManyToMany(targetEntity="Application\Entity\PhoneNumber")
  * @ORM\JoinTable(name="user_phone_number_linker",
  *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
  *      inverseJoinColumns={@ORM\JoinColumn(name="phone_number_id", referencedColumnName="id")}
  *      )
  */
  protected $phone_numbers;

ユーザーを参照すると、会社に同じ電話番号エンティティクラスを使用できないため、双方向のものを作成できないため、単方向の1対多を使用します。今ではすべて問題なく動作していますが、電話番号を削除すると次のエラーが表示されます:「DELETE FROM phone_number WHERE id = ?」の実行中に例外が発生しました。パラメータ {"1":1}:

SQLSTATE[23000]: 整合性制約違反: 1451 親行を削除または更新できません: 外部キー制約が失敗しました ( database/user_phone_number_linker, CONSTRAINT user_phone_number_linker_ibfk_11FOREIGN KEY ( phone_number_id) REFERENCES phone_number( id))

データベースで ON DELETE CASCADE 値を手動で設定すると問題なく動作しますが、これは doctrine2 を使用するという考えではなく、phpMyAdmin パネルに行かなくてもコード内で解決できるはずです。何らかの方法で、電話番号から結合テーブルへのカスケードを削除時に開始する必要がありますが、phone_number エンティティから結合テーブルへの参照を戻すことはありません。

賢い人がこれを解決するのを手伝ってくれることを願っています。

編集

その間、私は Doctrine2 についてさらに多くのことを学び、以前の質問を見直して、そもそもこれが複数の phoneNumbers を 1 つのテーブルに格納する正しい方法ではないことに気付きました。ユーザーの電話番号と会社の電話番号を同じテーブルに格納できるようにするには、テーブルの継承と識別子列を使用する必要があります。列には、ユーザー/会社の識別子が含まれている必要があります。

この列により、doctrine ORM はその phoneNumber が実際にユーザーまたは会社の電話番号であるかどうかを「認識」します。doctrine 2 spec の単一テーブル継承マッピング原則に従って、2 つの異なるエンティティ定義を作成する必要があります。

1 つのクラスUserPhoneNumberは、とのmany-to-one関係とUser呼ばれる他のクラスとCompanyPhoneNumberone-to-many関係を持ちCompanyます。結合列は必ずしも必要ではありません。user_idまたはcompany_id列は電話番号テーブルにある場合があります。UserクラスではCompany関連付けが省略され、クラスCompanyではUser関連付けが省略されます (データベースはこれらの列に null 値を許可する必要があります)。

結合テーブルを使用する場合は、Doctrine2 仕様の結合テーブルを使用した 1 対多の一方向の説明に従っています。

続きを読む

それ以外の場合は、この精巧なDoctrine2 の詳細なWeb サイトで、関連付けとカスケードの問題について詳しく読むこともできます。

4

2 に答える 2

1

あなたが言ったように、あなたの関係は一方向です。Users から PhoneNumbers への関係を定義しました。カスケード削除は、ユーザーを削除すると機能します。定義した関係であるため、user_phone_number_linker のすべての行が削除されます。

別の方法で行いたい場合は、PhoneNumbers から Users への関係を作成する必要があります。Doctrine が機能するにはそれが必要です。しかし、エンティティが他の 2 つのエンティティ (ユーザーと企業) によって共有されているという問題があります。

エンティティはテーブルではなくオブジェクトであることに注意してください。したがって、同じテーブルに 2 つのエンティティを作成することができます。1 つは PhoneNumberUsers という名前で、もう 1 つは PhoneNumberCompanies です。このようにして、カスケード削除を行うために必要なリレーションを作成できます。私は自分でテストしていませんが、うまくいくと思います。

ちなみに、ユーザーのエンティティ結合テーブルの oncascade パラメータを削除できます。私はユーザーとロールについてあなたと同じシナリオを持っていますが、私はそれを使用していません。エンティティからエンティティにカスケードしたい場合にのみ必要だと思います。それについてはよくわかりませんが、それは私が今まで経験してきたことです。

于 2013-04-04T19:34:21.327 に答える
0

残念ながら、電話番号のユーザー関係は多対多の関係と見なされるため、電話番号を削除したい場合は、電話番号自体を削除するだけでなく、ユーザーからも電話番号を明示的に削除する必要があります. したがって、コントローラーでは次のようになります。

// Remove the phone number user connection from the database
$user->removePhoneNumber($phone_number);

// Remove the phone number from the database
$em->remove($phone_number);

単方向の一対多との関係を作る独特の制限は、ドクトリンがそれを処理するのに十分だと思いました。それは正しくありませんでした。

于 2013-04-08T16:19:36.233 に答える