删除多对多表中的记录

Fra*_*hoa 18 doctrine many-to-many dql symfony

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

有一个表USERS和一个例子GROUPS.有一个许多一对多的关系USERSGROUPS,这在数据库称为表中创建USERGROUPS.

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

DELETE from USERGROUPS WHERE user_id = 1 and group_id = 1 
Run Code Online (Sandbox Code Playgroud)

我不知道怎么做,因为我没有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));
Run Code Online (Sandbox Code Playgroud)

我希望你明白这个主意.

那么,我该如何从这张表中删除?

Eth*_*han 19

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
Run Code Online (Sandbox Code Playgroud)

注意:如果你的用户模型中没有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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果与该用户相关的多对多表中有1,000,000条记录,我只需删除一条记录,该怎么办?Doctrine会加载所有记录吗? (3认同)

Sit*_*thu 5

除了@ Ethan的回答,单向删除不起作用.对于这种manyToMany关系,您必须remove从两个实体调用方法,例如,

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

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

$em->persist($user);
$em->flush();
Run Code Online (Sandbox Code Playgroud)