Symfony2,Doctrine:如何查询集合字段?很多关系

时间:2014-01-15 16:04:41

标签: symfony doctrine-orm many-to-many query-builder

我正在试图弄清楚是否有可能查询这样的事情(因为我无法使其工作)

$query = $em->createQuery("SELECT l FROM Bundle\EngMgmtBundle\Entity\Project p, 
                                      Bundle\EngMgmtBundle\Entity\Line l,
                                      Bundle\EngMgmtBundle\Entity\Site s 
                                      WHERE p.leader = :usr AND p.sites = s.id AND s.line = l.id");
            $query->setParameter('usr', $this->get('security.context')->getToken()->getUser());

我明白了:

[Semantical Error] line 0, col 289 near 'sites = s.id': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected. 

意思是我不能直接在project.sites上查询,就像我正在做的那样......我怎么能把它转过来让它起作用?

信息:

我有这些实体:Project,Line,Site,我需要查询与记录用户负责的项目(或项目)相关的所有行(领导者)。我之前没有使用ManyToMany关系之前就已经进行了这类查询。

项目有许多站点,许多站点属于许多项目,站点有一条线,一条线有很多站点。

这是每个实体的基本结构:

项目:

class Project
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
      * @ORM\ManyToOne(targetEntity="Bundle\UserBundle\Entity\User")
      * @ORM\JoinColumn(name="leader_id", referencedColumnName="id",nullable=false)
      */
    private $leader;

    /**
      * @ORM\ManyToOne(targetEntity="Bundle\ClientBundle\Entity\Client")
      * @ORM\JoinColumn(name="client_id", referencedColumnName="id",nullable=false)
      */
    private $client;

     /**
     * @ORM\ManyToMany(targetEntity="Bundle\EngMgmtBundle\Entity\Site")
     * @ORM\JoinTable(name="Project_Sites",
     *      joinColumns={@ORM\JoinColumn(name="site_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="project_id", referencedColumnName="id")}
     *      )
     */
    private $sites;

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

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Project
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set leader
     *
     * @param string $leader
     * @return Project
     */
    public function setLeader(\Bundle\UserBundle\Entity\User $leader)
    {
        $this->leader = $leader;

        return $this;
    }

    /**
     * Get leader
     *
     * @return string 
     */
    public function getLeader()
    {
        return $this->leader;
    }

    /**
     * Set client
     *
     * @param string $client
     * @return Project
     */
    public function setClient(\Bundle\ClientBundle\Entity\Client $client)
    {
        $this->client = $client;

        return $this;
    }

    /**
     * Get client
     *
     * @return string 
     */
    public function getClient()
    {
        return $this->client;
    }

    /**
     * Get Sites
     *
     * @return array 
     */
    public function getSites()
    {
        return $this->sites;
    }

    /* Returns Project's Name */
    public function __toString() 
    {
        return $this->name;
    }
}

网站:

class Site
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
      * @ORM\ManyToOne(targetEntity="Bundle\EngMgmtBundle\Entity\Line")
      * @ORM\JoinColumn(name="line_id", referencedColumnName="id",nullable=false)
      */
    private $line;

    /**
     * @var string
     *
     * @ORM\Column(name="latitude", type="string", length=255)
     */
    private $latitude;

    /**
     * @var string
     *
     * @ORM\Column(name="longitude", type="string", length=255)
     */
    private $longitude;

    /**
     * @var string
     *
     * @ORM\Column(name="internal_id", type="string", length=255, nullable=true)
     */
    private $internalId;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
      * @ORM\ManyToOne(targetEntity="Bundle\EngMgmtBundle\Entity\Priority")
      * @ORM\JoinColumn(name="priority_id", referencedColumnName="id",nullable=false)
      */
    private $priority;

    /**
      * @ORM\ManyToOne(targetEntity="Bundle\EngMgmtBundle\Entity\Location")
      * @ORM\JoinColumn(name="location_id", referencedColumnName="id",nullable=false)
      */
    private $state;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set line
     *
     * @param string $line
     * @return Site
     */
    public function setLine(\Bundle\EngMgmtBundle\Entity\Line $line)
    {
        $this->line = $line;

        return $this;
    }

    /**
     * Get line
     *
     * @return string 
     */
    public function getLine()
    {
        return $this->line;
    }

    /**
     * Set latitude
     *
     * @param string $latitude
     * @return Site
     */
    public function setLatitude($latitude)
    {
        $this->latitude = $latitude;

        return $this;
    }

    /**
     * Get latitude
     *
     * @return string 
     */
    public function getLatitude()
    {
        return $this->latitude;
    }

    /**
     * Set longitude
     *
     * @param string $longitude
     * @return Site
     */
    public function setLongitude($longitude)
    {
        $this->longitude = $longitude;

        return $this;
    }

    /**
     * Get longitude
     *
     * @return string 
     */
    public function getLongitude()
    {
        return $this->longitude;
    }

    /**
     * Set internalId
     *
     * @param string $internalId
     * @return Site
     */
    public function setInternalId($internalId)
    {
        $this->internalId = $internalId;

        return $this;
    }

    /**
     * Get internalId
     *
     * @return string
     */
    public function getInternalId()
    {
        return $this->internalId;
    }
/**
     * Set name
     *
     * @param string $name
     * @return Site
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Set priority
     *
     * @param string $priority
     * @return Site
     */
    public function setPriority(\Bundle\EngMgmtBundle\Entity\Priority $priority)
    {
        $this->priority = $priority;

        return $this;
    }

    /**
     * Get priority
     *
     * @return string 
     */
    public function getPriority()
    {
        return $this->priority;
    }
        /**
     * Set state
     *
     * @param string $state
     * @return Site
     */
    public function setState(\Bundle\EngMgmtBundle\Entity\Location $state)
    {
        $this->state = $state;

        return $this;
    }

    /**
     * Get state
     *
     * @return string 
     */
    public function getState()
    {
        return $this->state;
    }
    /* Returns Site's Name */
    public function __toString() 
    {
        return $this->name;
    }

行:

class Line
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
      * @ORM\OneToOne(targetEntity="Bundle\UserBundle\Entity\User")
      * @ORM\JoinColumn(name="supervisor_id", referencedColumnName="id",nullable=false)
      */
    private $supervisor;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Line
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set supervisor
     *
     * @param string $supervisor
     * @return Line
     */
    public function setSupervisor(\Bundle\UserBundle\Entity\User $supervisor)
    {
        $this->supervisor = $supervisor;

        return $this;
    }

    /**
     * Get supervisor
     *
     * @return string 
     */
    public function getSupervisor()
    {
        return $this->supervisor;
    }

     /* Returns Line's Name */
    public function __toString() 
    {
        return $this->name;
    }

我真的很感激你能提供给我的任何帮助。提前致谢。

1 个答案:

答案 0 :(得分:1)

你的代码在哪里?从获取安全上下文的方式来看,我猜它可能在控制器中?也许这个查询应该放在Project实体的存储库方法中?我想使用查询生成器是最简单的方法来做这样的事情。我无法对此进行测试,因此它可能无法通过复制和粘贴来工作,但希望它无论如何都会变得模糊:

    $em->createQueryBuilder('p')
        ->select('p', 's', 'l')
        ->leftJoin('p.sites', 's')
        ->leftJoin('s.line', 'l')
        ->where('p.leader = :user')
        ->setParameter('user', $user)
        ->getQuery()
        ->getResult();