我在两个实体之间存在正常的多对多关系:用户和对象。
________ _________________ ____________
| User | | User_Object | | Object |
|------| |---------------| |----------|
| id | | user_id | | id |
| .... | | object_id | | .... |
|______| |_______________| |__________|
我想批量删除相当大的用户集(以及与User_Object表中的相关记录)。逐个删除实体并不足以满足我的需求(对于> 1000个实体,它需要一个loooonnnng时间)。
//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);
//...
doctrine docs说批量删除实体最有效的是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
答案 0 :(得分: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;
这是一个例子。我没有测试过它。