删除多对多表中的记录

时间:2012-03-11 08:22:27

标签: doctrine symfony many-to-many dql

我正在关注Symfony 2书的安全章节。

有一个表USERSGROUPS的示例。 USERSGROUPS之间存在多对多关系,这会在数据库中创建一个名为USERGROUPS的表。

我想要的是从USERGROUPS删除记录,例如:

DELETE from USERGROUPS WHERE user_id = 1 and group_id = 1 

我不知道怎么做,因为我没有USERGROUPS.php表格文件。

例如,使用DQL,我希望能够这样做:

$em = $this->getDoctrine()->getEntityManager();
$query = $em->createQuery(
    'DELETE FROM AcmeStoreBundle:UserGroups ug WHERE ug.user_id = :user 
    and ug.group_id = :group'
)->setParameter(array('user' => $userid, 'group' => $groupid));

我希望你明白这一点。

然后,如何从此表中删除?

2 个答案:

答案 0 :(得分:20)

Doctrine将数据视为对象,而不是表行。因此,在Doctrine术语中,有Group对象(其中包含Group的用户)以及User对象(每个对象都有一个属性,用于存储用户所在的Groups)。但是没有UserGroup对象。 Doctrine(以及任何ORM系统)的想法是让开发人员忘记数据库可能需要的这些中间表,但这些中间表在程序的对象模型方面是不必要的。

所以你想要做的是加载相关的User对象,从它的$ groups属性中删除该组,并保留修改后的User对象。 (反之亦然,即加载相关的Group对象并从中删除用户。)DQL可能能够处理这个问题,但我认为没有DQL更容易,因为DQL的DELETE语句用于删除整个对象,而不是修改他们的财产。

尝试:

$user = $em->find('User', $userId);
$user->removeGroup($groupId); //make sure the removeGroup method is defined in your User model. 
$em->persist($user);
$em->flush(); //only call this after you've made all your data modifications

注意:如果你的用户模型中没有removeGroup()方法(我认为Symfony可以为你生成一个,但我可能错了),该方法可能如下所示。

//In User.php, and assuming the User's groups are stored in $this->groups, 
//and $groups is initialized to an empty ArrayCollection in the User class's constructor
//(which Symfony should do by default).

class User
{
    //all your other methods

    public function removeGroup($group)
    {
        //optionally add a check here to see that $group exists before removing it.
        return $this->groups->removeElement($group);
    }
}

答案 1 :(得分:5)

除了@ Ethan的回答,单向删除无法正常工作。对于此类manyToMany关系,您必须从两个实体调用remove方法,例如,

$user = $em->findOneById($userId);
$group = $em->findOneById($groupId);

$user->removeGroup($group);
$group->removeUser($user);

$em->persist($user);
$em->flush();