嗨,大家好,我有兩個對象當我從存儲庫中使用自定義DQL獲得點和子點時,我想按字段ord排序點,並將子點排序到字段ord。Symfony 2 doctrine DQL order by two fields
這裏是實體:
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;
}
}
庫點,在這裏,我想,當我點到由奧德被oredered並通過ORD訂購的subpoints:
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();
}
}
但是當我把在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();
}
你有什麼好理由使用原則,並仍然建立查詢字符串*手?*?這裏有嚴重的問題。使用['setParameter'](https://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html)或類似的。 – Yoshi
你是對的參數,但問題是在秩序聲明,它是在第二順序不在參數對象。 –
我暗示的是,當你正確地建立查詢時,你一定會有更容易的時間修復訂單問題。例如。使用查詢生成器,您可以根據需要簡單地添加'addOrderBy()'多次。也就是說,可能會添加* renderd * dql,所以我們可以在不猜測'$ object'可以做什麼的情況下看到它。 – Yoshi