学说2,如何删除多对多关联?

时间:2011-09-04 13:29:32

标签: doctrine doctrine-orm

如何在不删除任何内容的情况下从多对多表中取消关联?

我试过了:

$getProject = $this->_helper->getDocRepo('Entities\Project')->findOneBy(array('id' => $projectId));
$getCat = $this->_doctrine->getReference('\Entities\Projectcat', $catId);

$getProject->getCategory()->removeElement($getCat);
$this->em->flush();

我的Projectcat实体:

/**
 * @ManyToMany(targetEntity="\Entities\Projectcat", cascade={"persist", "remove"})
 * @JoinColumn(name="id", referencedColumnName="id")
 */
protected $getCategory;

3 个答案:

答案 0 :(得分:9)

您的信息有限。关于数据库方案和项目的一些额外信息会很好。但试试看。

你必须从关系的两边删除它。您已从类别中删除它,但您也应将其从项目中删除。

// Remove Category from Project
$Project->Category->removeElement($Category);
// Remove Project from Category
$Category->Project->removeElement($Project);
祝你好运!

答案 1 :(得分:8)

一个相当古老的帖子,但希望提供一种方法来确保从ORM实体方面的学说中删除关联,而不是必须手动执行每个Entity的集合removeElement并通过@扩展答案Rene Terstegen。

问题在于,学说并不是自动神奇的#34;将关联绑定在一起,您可以更新实体的添加/删除方法。

https://gist.github.com/Ocramius/3121916

以下示例基于OP的项目/类别架构。 它假定表project_categoryManyToMany关系表,projectcategory表使用主键id

class Project
{

    /**
     * @ORM\ManyToMany(targetEntity="Category", inversedBy="projects")
     * @ORM\JoinTable(
     *  name="project_category",
     *  joinColumns={
     *      @ORM\JoinColumn(name="project", referencedColumnName="id")
     *  },
     *  inverseJoinColumns={
     *      @ORM\JoinColumn(name="category", referencedColumnName="id")
     *  }
     * )
     */
    protected $categories;

    public function __construct()
    {
        $this->categories = new ArrayCollection();
    }

    /**
     * @param Category $category
     */
    public function removeCategory(Category $category)
    {
        if (!$this->categories->contains($category)) {
            return;
        }    
        $this->categories->removeElement($category);
        $category->removeProject($this);
    }
}

class Category
{    
    /**
     * @ORM\ManyToMany(targetEntity="Project", mappedBy="categories")
     */
    protected $projects;

    public function __construct()
    {
        $this->projects = new ArrayCollection();
    }

    /**
     * @param Project $project
     */
    public function removeProject(Project $project)
    {
        if (!$this->projects->contains($project)) {
            return;
        }    
        $this->projects->removeElement($project);
        $project->removeCategory($this);
    }
}

然后您需要做的就是调用removeCategoryremoveProject方法,而不是两者。同样适用于addCategoryaddProject方法。

$project = $em->find('Entities\Project', $projectId);
$category = $em->getReference('Entities\Category', $categoryId);
$project->removeCategory($category);
$em->flush();

答案 2 :(得分:0)

一篇旧帖子,但上面的答案对我有所帮助,但它可能有助于扩展它,我有一个项目可以有很多类别(和类别可以有很多项目),所以这个代码让我全部他们:

$project->getCategories();

如果我想删除项目的所有类别,我只需执行此操作:

 foreach ($project->getCategories() as $category) {
    $project->getCategories()->removeElement($category);
 }

原始问题的问题在于我相信Doctrine希望您传入项目引用的类别,而不仅仅是使用此代码独立获取的类别的引用:

$getCat = $this->_doctrine->getReference('\Entities\Projectcat', $catId);

希望这是有道理的。我知道我正在搞这个术语。