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']]);
我有以下功能:
/**
*
* {@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']]);