大家好我有两个对象Point和Subpoint,当我从自定义DQL的存储库中获取点我想点按字段ord和Subpoints to field ord。
以下是实体:
namespace George\ArchitectureBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model\Translatable\Translatable;
use Doctrine\Common\Collections\ArrayCollection;
use Gedmo\Mapping\Annotation as Gedmo;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
/**
* Point
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="George\ArchitectureBundle\Entity\PointRepository")
* @Vich\Uploadable
*/
class Point
{
use Translatable;
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var Object
* @Gedmo\SortableGroup
* @ORM\ManyToOne(targetEntity="George\ObjectsBundle\Entity\Object", inversedBy="architecturespoints")
* @ORM\JoinColumn(name="object_id", referencedColumnName="id")
*/
private $object;
/**
* @ORM\OneToMany(targetEntity="George\ArchitectureBundle\Entity\Subpoint", mappedBy="point")
*/
private $subpoints;
/**
* @var integer
* @Gedmo\SortablePosition
* @ORM\Column(name="ord", type="integer")
*/
private $ord;
/**
* @var \DateTime
* @Gedmo\Timestampable(on="update")
* @ORM\Column(name="updated", type="datetime")
*/
private $updated;
/**
* @var \DateTime
* @Gedmo\Timestampable(on="create")
* @ORM\Column(name="created", type="datetime")
*/
private $created;
public function __construct()
{
$this->subpoints = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* @return Object
*/
public function getObject()
{
return $this->object;
}
/**
* @param Object $object
*/
public function setObject($object)
{
$this->object = $object;
}
/**
* @return int
*/
public function getOrd()
{
return $this->ord;
}
/**
* @param int $ord
*/
public function setOrd($ord)
{
$this->ord = $ord;
}
/**
* @return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* @return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* @return mixed
*/
public function getSubpoints()
{
return $this->subpoints;
}
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @Vich\UploadableField(mapping="point_image", fileNameProperty="imageName")
*
* @var File
*/
private $imageFile;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
* @var string
*/
private $imageName;
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
// $this->setModefied(new \DateTime('now')) ;
}
}
/**
* @return File
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* @param string $imageName
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
}
/**
* @return string
*/
public function getImageName()
{
return $this->imageName;
}
}
下点:
namespace George\ArchitectureBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use Knp\DoctrineBehaviors\Model\Translatable\Translatable;
use Gedmo\Mapping\Annotation as Gedmo;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
/**
* Subpoint
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="George\ArchitectureBundle\Entity\SubpointRepository")
* @Vich\Uploadable
*/
class Subpoint
{
use Translatable;
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var Points
* @Gedmo\SortableGroup
* @ORM\ManyToOne(targetEntity="George\ArchitectureBundle\Entity\Point", inversedBy="subpoints")
*/
private $point;
/**
* @var integer
* @Gedmo\SortablePosition
* @ORM\Column(name="ord", type="integer")
*/
private $ord;
/**
* @var \DateTime
* @Gedmo\Timestampable(on="update")
* @ORM\Column(name="updated", type="datetime")
*/
private $updated;
/**
* @var \DateTime
* @Gedmo\Timestampable(on="create")
* @ORM\Column(name="created", type="datetime")
*/
private $created;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* @return Points
*/
public function getPoint()
{
return $this->point;
}
/**
* @param Points $point
*/
public function setPoint($point)
{
$this->point = $point;
}
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @Vich\UploadableField(mapping="point_image", fileNameProperty="imageName")
*
* @var File
*/
private $imageFile;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
* @var string
*/
private $imageName;
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
// $this->setModefied(new \DateTime('now')) ;
}
}
/**
* @return File
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* @param string $imageName
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
}
/**
* @return string
*/
public function getImageName()
{
return $this->imageName;
}
/**
* @return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* @return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* @return int
*/
public function getOrd()
{
return $this->ord;
}
/**
* @param int $ord
*/
public function setOrd($ord)
{
$this->ord = $ord;
}
}
Repository Point和我想要的当我得到了ord和ord要求的子点:
namespace George\ArchitectureBundle\Entity;
/**
* PointRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class PointRepository extends \Doctrine\ORM\EntityRepository
{
public function getPointsByObject($object)
{
$em = $this->getEntityManager();
$query = $em->createQuery("SELECT p FROM George\ArchitectureBundle\Entity\Point p WHERE p.object =".$object." ORDER BY p.ord ASC");
return $query->getResult();
}
}
但是当我在Point存储库中放入creatQuery时
"SELECT p FROM George\ArchitectureBundle\Entity\Point p WHERE p.object =".$object." ORDER BY p.ord ASC, p.subpoints.ord ASC "
我收到了错误:
[Semantical Error] line 0, col 107 near 'ord ASC ': Error: Class George\ArchitectureBundle\Entity\Point has no field or association named subpoints.ord
修改 问题的解决方案是使用@Yoshi和@Veve的指导查询构建器:
public function getPointsByObject($object)
{
$em = $this->getEntityManager();
// $query = $em->createQuery("SELECT p FROM George\ArchitectureBundle\Entity\Point p left join George\ArchitectureBundle\Entity\Subpoint s WITH s.point = p WHERE p.object =".$object." ORDER BY p.ord ASC, s.ord ASC");
$qb = $em->createQueryBuilder();
$qb->select('p')
->from('George\ArchitectureBundle\Entity\Point','p')
->where(' p.object =:object')
->leftJoin('George\ArchitectureBundle\Entity\Subpoint', 's', 'WITH', 's.point = p')
->orderBy('p.ord','ASC')
->orderBy('s.ord','ASC');
$qb->setParameters(array(
'object' => $object
));
$query= $qb->getQuery();
return $query->getResult();
}