2

ユーザーとオブジェクトの2つのエンティティ間に通常の多対多の関係があります。

________        _________________        ____________
| User |        |   User_Object |        |  Object  |
|------|        |---------------|        |----------|
|  id  |        |     user_id   |        |    id    |
| .... |        |    object_id  |        |   ....   |
|______|        |_______________|        |__________|

かなり大きなユーザー セット (および User_Object テーブルでそれらに関連付けられているレコード) を一括削除したいと考えています。エンティティを 1 つずつ削除しても、私のニーズには十分な速度ではありません (エンティティが 1000 を超えると、かなりの時間がかかります)。

//This method is far too slow for my needs
$qb = $this->doctrine->em->createQueryBuilder();
$qb->select('u')
    ->from('Entities\User', 'u')
    ->where("u.whatever= ?1")
    ->setParameter(1, $whatever);
$users = $qb->getQuery()->getResult();

foreach($users as $user)
{
    $this->doctrine->em->remove($user);
    //...

教義のドキュメントによると、エンティティを一括削除するのに最も効率的なのは DQL であり、次のようなものが得られます。

$qb = $this->doctrine->em->createQuery('delete from Entities\User u where u.whatever = ?1');
$qb->setParameter(1, $whatever);
$numDeleted = $qb->execute(); //This will throw because of User_Object records

これにより、User_Object 結合テーブル内のレコードが原因で例外がスローされます (参照整合性例外)。

だから、私の質問は次のとおりです。一括削除シナリオで結合テーブルのレコードを効率的に削除するにはどうすればよいですか。

生の SQL をスローすることは本当に避けたいと思います。コードの残りの部分はあらゆる場所でエンティティを使用しており、可能であればその方法を維持したいと考えています。

編集:関係はそのようにマークされています(私はymlを使用します):

manyToMany:
  objects:
  targetEntity: Object
  inversedBy: users
  cascade: ["remove"]
  joinTable:
    name: User_Object
    joinColumns:
      user_id:
        referencedColumnName: id
    inverseJoinColumns:
      object_id:
        referencedColumnName: id
4

1 に答える 1

0

オブジェクトのユーザーを削除する場合、doctrine の動作をセットアップしていません。ユーザーが削除された場合、関連するすべてのオブジェクトも削除する必要があるという教義を言わなければなりません。

/**
 * @ORM\ManyToMany(targetEntity="User", mappedBy="objects", cascade={"remove"})
 */
protected $users;


/**
 * @ORM\ManyToMany(targetEntity="Object", inversedBy="users", cascade={"persist", "remove"})
 * @ORM\JoinTable(name="user_object",
 * joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
 * inverseJoinColumns={@ORM\JoinColumn(name="object_id", referencedColumnName="id")}
 * )
 */
protected $objects;

これは一例です。私はそれをテストしませんでした。

于 2013-11-04T16:42:00.297 に答える