Symfony 3 Doctrine Select 与关系

Symfony 3 Doctrine Select with Relantionship

我有以下功能:

 /**
     *
     * {@inheritDoc}
     * @see \AppBundle\Interfaces\CrudManagerInterface::search()
     *
     * @return Member[]
     */
    public function search(array $searchParams, array $order , $page, $limit)
    {
        /**
         * @var \Doctrine\Common\Persistence\ObjectRepository $queryBuilder
         */
        $queryBuilder=$this->entityManager->createQueryBuilder();

        $queryBuilder=$queryBuilder->select('m')->from('AppBundle:Member','m');

        if(!empty($searchParams['name']))
        {
            $queryBuilder->andWhere('m.name LIKE :name')->setParameter('name','%'.$searchParams['name'].'%');
        }

        if(!empty($searchParams['schools']))
        {
            if(!is_array($searchParams['schools']))
            {
                $searchParams['schools']=[$searchParams['schools']];
            }

            $queryBuilder->andWhere('m.schools IN ( Select s.id FROM AppBundle:Schools s WHERE s.id IN (:schools ) )')->setParameters(['schools'=>$searchParams['schools']]);
        }

        if(!empty($order))
        {
            if(isset($searchParams['name']))
            {
                $queryBuilder->addOrderBy('m.name',$order['name']);
            }
        }

        if((int)$limit>0)
        {
            $queryBuilder->setFirstResult((int)$page)->setMaxResults($limit);
        }


        /**
         * @var Doctrine\ORM\Query
         */
        $query=$queryBuilder->getQuery();

        $queryString=$query->getDql();

        $results=$query->getResult();
        return $results;
    }

以及以下实体:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use AppBundle\Interfaces\ArrayAbleInterface;

/**
 * @ORM\Entity
 * @ORM\Table(name="members")
 */
class Member implements ArrayAbleInterface
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $email;

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

    /**
     * @ORM\ManyToMany(targetEntity="School",mappedBy="members")
     * @ORM\JoinTable(name="members_have_schools")
     */
    private $schools;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->schools = new \Doctrine\Common\Collections\ArrayCollection();
    }

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

    /**
     * Set email
     *
     * @param string $email
     *
     * @return Member
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

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

    /**
     * Add school
     *
     * @param \AppBundle\Entity\School $school
     *
     * @return Member
     */
    public function addSchool(\AppBundle\Entity\School $school)
    {
        $school->addMember($this);
        $this->schools[] = $school;

        return $this;
    }

    /**
     * Remove school
     *
     * @param \AppBundle\Entity\School $school
     */
    public function removeSchool(\AppBundle\Entity\School $school)
    {
        $this->schools->removeElement($school);
    }

    /**
     * Get schools
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getSchools()
    {
        return $this->schools;
    }

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

        return $this;
    }

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

    /**
     * {@inheritDoc}
     * @see \AppBundle\Interfaces\ArrayAbleInterface::toArray()
     */
    public function toArray()
    {
        $array=['id'=>$this->getId(),'name'=>$this->getName(),'email'=>$this->getEmail(),'schools'=>array()];

        $schools=$this->getSchools()->getValues();

        foreach($schools as $school)
        {
            $array['schools'][]=$school->toArray();
        }

        return $array;
    }
}

<?php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use AppBundle\Interfaces\ArrayAbleInterface;

/**
 * @ORM\Entity
 * @ORM\Table(name="schools")
 */
class School implements ArrayAbleInterface
{
    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

    /**
     *
     * @var unknown
     */
    private $school_id;

    /**
     * @var unknown
     * @ORM\ManyToMany(targetEntity="Member", inversedBy="schools")
     */
    private $members;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->members = new \Doctrine\Common\Collections\ArrayCollection();
    }

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

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

        return $this;
    }

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

    /**
     * Add member
     *
     * @param \AppBundle\Entity\Member $member
     *
     * @return School
     */
    public function addMember(\AppBundle\Entity\Member $member)
    {
        $this->members[] = $member;

        return $this;
    }

    /**
     * Remove member
     *
     * @param \AppBundle\Entity\Member $member
     */
    public function removeMember(\AppBundle\Entity\Member $member)
    {
        $this->members->removeElement($member);
    }

    /**
     * Get members
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getMembers()
    {
        return $this->members;
    }

    /**
     *
     * {@inheritDoc}
     * @see \AppBundle\Interfaces\ArrayAbleInterface::toArray()
     */
    public function toArray()
    {
        $array=['id'=>$this->getId(),'name'=>$this->getName()];

        return $array;
    }
}

使用顶部提到的函数,我想搜索名称和一些学校 ID 作为数组给出的成员。所有这些都在 $searchParams 数组中。但是我找不到用学校 ID 搜索的方法。

$searchParams 的示例参数是:

[
  'name'=>'Sailor'
  'schools'=>[1,2,3]
]

我的数据库中的一些示例数据是

成员:

> id|  name           | email              |
> 1 |  Sailor Mooon   | sailor@moon.com    |
> 2 | Monk1ey D Luffy | monkey.d@luffy.com |

学校

> id | name 
> 1  | Kokoro Daigaku
> 2  | Oumi Akademy
> 3  | Univercity of Pokemon Battle

在上面提到的函数中我得到以下错误:

: [Semantical Error] line 0, col 71 near 'id IN ( Select': Error: Class AppBundle\Entity\Member has no field or association named schools.id [] []

你能帮我解决一下吗?

编辑 1

我设法通过更改以下部分解决了问题:

$queryBuilder->andWhere('m.schools IN ( Select s.id FROM AppBundle:Schools s WHERE s.id IN (:schools ) )')->setParameters(['schools'=>$searchParams['schools']]);

进入这个:

$queryBuilder->join('AppBundle:School','s')->andWhere('s.id IN (:schools)')->setParameters(['schools'=>$searchParams['schools']]);

但我得到的会员与任何学校都没有关系。

最后我改了:

$queryBuilder->join('AppBundle:School','s')->andWhere('s.id IN (:schools)')->setParameters(['schools'=>$searchParams['schools']]);

进入这个:

$queryBuilder->join('m.schools','s')->andWhere('s.id IN (:schools)')->setParameters(['schools'=>$searchParams['schools']]);