2016-01-15 2 views
0

Привет, ребята, у меня есть два объекта. Точка и подпункт, когда я получил из репозитория с настраиваемым DQL. Точка, которую я хочу заказать Points по полю ord и Subpoints в поле ord.Symfony 2 doctrine Порядок DQL по двум полям

Вот ПРИМИТИВЫ:

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 Точка и здесь я хочу, когда я получил точку быть oredered на Орд и подпункты, которые можно заказать по 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(); 


} 
} 

Но когда я положил в 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 

EDIT Решение проблемы это с построитель запросов с руководством @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(); 


} 
+2

По какой причине вы бы использовали доктрину и все еще строят строки запроса * вручную *? Здесь что-то серьезно не так. Используйте ['setParameter'] (https://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html) или аналогичный. – Yoshi

+0

Вы правы в параметрах, но вопрос находится в инструкции порядка, и он находится во втором порядке не в объекте параметра. –

+1

Что я подразумеваю, так это то, что когда вы правильно строите запрос, вам наверняка будет легче решить проблему заказа. Например. используя построитель запросов, вы можете просто добавить 'addOrderBy()' столько раз, сколько вам нужно. Тем не менее, возможно, добавьте * renderd * dql, чтобы мы могли видеть это, не догадываясь, что может сделать '$ object'. – Yoshi

ответ

2

Вы должны присоедините подпункт к порядку по одному из следующих атрибутов:

"SELECT p FROM George\ArchitectureBundle\Entity\Point p 
JOIN George\ArchitectureBundle\Entity\Subpoint s WITH s.point = p.id 
WHERE p.object =".$object." 
ORDER BY p.ord ASC, s.ord ASC" 

И как Yoshicommented, вы должны использовать queryBuilder и добавлять к нему свои параметры вместо того, чтобы строить запрос вручную.

+0

Спасибо, что мне просто нужно было заменить на С –

+0

Вы правы, исправлены. – Veve

+0

Вы также можете сделать 'JOIN p.subpoints s'. – xabbuh

Смежные вопросы