删除多对多表中的记录

时间:2022-10-05 13:14:43

I'm following the security chapter of the Symfony 2 book.

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

There's is an example with a table USERS and GROUPS. There is a many-to-many relationship between USERS and GROUPS, which creates in the database a table called USERGROUPS.

有一个表USERS和GROUPS的例子。 USERS和GROUPS之间存在多对多关系,它在数据库中创建了一个名为USERGROUPS的表。

What I want is to delete a record from USERGROUPS, for example:

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

DELETE from USERGROUPS WHERE user_id = 1 and group_id = 1 

I don't know how to do this since I don't have an USERGROUPS.php table file.

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

Using DQL, for example, I want to be able to do this:

例如,使用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));

I hope you get the idea.

我希望你明白这个主意。

Then, how do I remove from this table?

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

2 个解决方案

#1


19  

Doctrine thinks about the data as objects, rather than as table rows. So, in Doctrine terms, there are Group objects (which hold the Group's users, among other things) and there are User objects (each one of which has a property storing the Groups that the user is in). But there are no UserGroup objects. The idea of Doctrine (and any ORM system) is to let the developer forget about these intermediate tables that the database might need but that aren't necessary in terms of the program's object model.

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

So what you want to do is load up the relevant User object, remove the group from it's $groups property, and persist the modified User object. (Or vice-versa, i.e. load up the relevant Group object and remove the User from it.) DQL might be able to handle this, but I think it's easier to do it without DQL as DQL's DELETE statement is for deleting whole objects, not modifying their properties.

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

Try:

尝试:

$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

Note: if you don't have a removeGroup() method in your User model (I think Symfony can generate one for you, but I could be wrong), the method could look as follows.

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

#2


5  

In addition to @Ethan's answer, one-way remove is not working. For such manyToMany relationship, you have to call the remove methods from both entities, for example,

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

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

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

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

#1


19  

Doctrine thinks about the data as objects, rather than as table rows. So, in Doctrine terms, there are Group objects (which hold the Group's users, among other things) and there are User objects (each one of which has a property storing the Groups that the user is in). But there are no UserGroup objects. The idea of Doctrine (and any ORM system) is to let the developer forget about these intermediate tables that the database might need but that aren't necessary in terms of the program's object model.

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

So what you want to do is load up the relevant User object, remove the group from it's $groups property, and persist the modified User object. (Or vice-versa, i.e. load up the relevant Group object and remove the User from it.) DQL might be able to handle this, but I think it's easier to do it without DQL as DQL's DELETE statement is for deleting whole objects, not modifying their properties.

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

Try:

尝试:

$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

Note: if you don't have a removeGroup() method in your User model (I think Symfony can generate one for you, but I could be wrong), the method could look as follows.

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

#2


5  

In addition to @Ethan's answer, one-way remove is not working. For such manyToMany relationship, you have to call the remove methods from both entities, for example,

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

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

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

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