简体   繁体   English

Symfony2如何使用querybuilder加入多对多关系?

[英]Symfony2 how to join on many-to-many relations using querybuilder?

Being new to symfony2 and querybuilder, I am trying to select all my containers but limiting the result to only those for which the logged-in user has access. 作为symfony2和querybuilder的新手,我试图选择所有容器,但将结果限制为仅登录用户有权访问的那些容器。

With the current code I get this error: 使用当前代码,我得到此错误:

Notice: Undefined index: Container in /var/www/biztv_symfony/vendor/doctrine/lib/Doctrine/ORM/Query/SqlWalker.php line 746 注意:未定义的索引:/var/www/biztv_symfony/vendor/doctrine/lib/Doctrine/ORM/Query/SqlWalker.php第746行中的容器

Here is my attempt at the query (I have tried a couple of options from this and other forum sites and still can't seem to understand it right...) 这是我对查询的尝试(我已经尝试了该站点和其他论坛站点中的几个选项,但似乎仍然无法正确理解...)

public function indexAction()
{
    //Get the requisits        
    $companyId = $this->container->get('security.context')->getToken()->getUser()->getCompany()->getId();
    $em = $this->getDoctrine()->getEntityManager();

    //Fetch the containers
    $repository = $this->getDoctrine()->getRepository('BizTVContainerManagementBundle:Container');
    $query = $repository->createQueryBuilder('c')
        ->innerJoin('c.users','u')
        ->where('c.company = :company')
        ->setParameter('company', $companyId)
        ->orderBy('c.name', 'ASC')
        ->getQuery();
    $containers = $query->getResult();

I keep track of access with a many-to-many relation, this is my user entity... 我通过多对多关系跟踪访问,这是我的用户实体...

<?php
// src/BizTV/UserBundle/Entity/User.php

namespace BizTV\UserBundle\Entity;

use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

use BizTV\BackendBundle\Entity\company as company;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;  

    /**
    * @var object BizTV\BackendBundle\Entity\company
    *  
    * @ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
    * @ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
    */
    protected $company; 

    /**
     * @ORM\ManyToMany(targetEntity="BizTV\ContainerManagementBundle\Entity\Container", inversedBy="User")
     * @ORM\JoinTable(name="access")
     */
    private $access;

    public function __construct()
    {
        parent::__construct();

        $this->access = new \Doctrine\Common\Collections\ArrayCollection();

    }
//getters and setters...

This is my container entity: 这是我的容器实体:

<?php

namespace BizTV\ContainerManagementBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

use BizTV\UserBundle\Entity\User as user;

/**
 * BizTV\ContainerManagementBundle\Entity\Container
 *
 * @ORM\Table(name="container")
 * @ORM\Entity
 */
class Container
{

    /**
     * @var integer $id
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string $name
     * @Assert\NotBlank(message = "Du måste ange ett namn för området") 
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;
    //TODO: form handler assuring no name is used twice in same company

    /**
    * @var object BizTV\BackendBundle\Entity\company
    *  
    * @ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
    * @ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
    */
    protected $company; 

    /**
     * @ORM\ManyToMany(targetEntity="BizTV\UserBundle\Entity\User", mappedBy="Container")
     */
    private $users;

    public function __construct() {
        $this->users = new \Doctrine\Common\Collections\ArrayCollection();
    }

In the Container entity, when you specify the $users property mapping, the value of mappedBy is important: you need to specify the name of the inverse property in the User class. Container实体中,当您指定$users属性映射时, mappedBy的值很重要:您需要在User类中指定相反属性的名称

Here, we have, Container::$users <-> User::$access . 在这里,我们有Container::$users <-> User::$access

Change your annotations to: 将注释更改为:

class User
{
    /**
     * @ORM\ManyToMany(targetEntity="BizTV\ContainerManagementBundle\Entity\Container", inversedBy="users")
     * @ORM\JoinTable(name="access")
     */
    private $access;
}

class Container
{
    /**
     * @ORM\ManyToMany(targetEntity="BizTV\UserBundle\Entity\User", mappedBy="access")
     */
    private $users;
}

I encourage you to read the doctrine orm documentation part about associations , and verify and fix this in all your associations. 我鼓励您阅读有关关联准则orm文档部分 ,并在所有关联中验证并修复此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM