Symfony 2学说DQL按两个字段顺序排列

时间:2016-01-15 09:19:39

标签: symfony doctrine-orm dql

大家好我有两个对象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();


}

1 个答案:

答案 0 :(得分: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"

作为Yoshi commented,您应该使用queryBuilder并使用它添加参数,而不是手动构建查询。