DQL试图获取父页面的名称。左连接不起作用

时间:2013-09-20 12:16:05

标签: php symfony doctrine one-to-one dql

很抱歉,如果标题有点令人困惑。想不出一个总结我要问的好方法。

在我正在构建的网站上,我需要允许页面包含子页面。我已经为这些页面编写了这样的路径:

/ category / parentName / childName(例如/ business / text-elements / links)

但是父和子都存在于同一个表中。我无法弄清楚如何编写查询以返回子页面。以下是我到目前为止的情况:

public function findByUrlJoinedToSectorAndParent($sector, $pageParent, $pageUrl)
{
    $query = $this->getEntityManager()
        ->createQuery('
            SELECT p, s FROM acmeStyleGuideBundle:PageContent p
            JOIN p.pageSector s
            LEFT JOIN p.pageTypes t
            WHERE p.pageUrl = :url
            AND s.sectorName = :sector
            AND p.PageParent = :parent
            AND t.typeName != :type'
        )
        ->setParameter('url', $pageUrl)
        ->setParameter('sector', $sector)
        ->setParameter('parent', $pageParent)
        ->setParameter('type', 'Section Headers');

    try {
        return $query->getResult();
    } catch (\Doctrine\ORM\NoResultException $e) {
        return null;
    }
}

现在,这确实有效。但是它与路线不匹配。目前,路线需要看起来像这样才能找到子页面:

/ category / parentID / childName(例如/ business / 2 / links)

我无法弄清楚如何编写查询以接受父名称,因为您可以看到我使用左连接以这种方式查询其他表但我不认为我可以将表连接到自身。

以下是PageContent的实体:

namespace acme\StyleGuideBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * PageContent
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="acme\StyleGuideBundle\Entity\pageContentRepository")
 */

class PageContent
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
        private $id;

    /**
     * @var ArrayCollection $pageSector_Id;
     * @ORM\ManyToMany(targetEntity="pageSector")
     * @ORM\JoinTable(
     *      name="pageSector_PageContent",
     *      joinColumns={@ORM\JoinColumn(name="PageContent_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="pageSector_Id", referencedColumnName="id")}
     *      )
     */
        protected $pageSector;

    /**
     * @ORM\ManyToOne(targetEntity="pageTypes", inversedBy="PageContent")
     * @ORM\JoinColumn(name="pageTypesId", referencedColumnName="id")
     */
        protected $pageTypes;

    /**
     * @var integer
     *
     * @ORM\Column(name="pageTypesId", type="integer")
     */

        private $pageTypesId;

    /**
     * @ORM\OneToOne(targetEntity="PageContent")
     * @ORM\JoinColumn(name="PageParent", referencedColumnName="id")
     */
        private $PageParent;

    /**
     * @var string
     *
     * @ORM\Column(name="pageName", type="string", length=255)
     */
        private $pageName;

    /**
     * @var string
     *
     * @ORM\Column(name="pageUrl", type="string", length=255)
     */
        private $pageUrl;

    /**
     * @var string
     *
     * @ORM\Column(name="richText", type="text")
     */
        private $richText;

    /** Converts string into sluggable url 
    *
    *   @return $text
    */
    public function slugify($text)
    {
        // replace non letter or digits by -
        $text = preg_replace('#[^\\pL\d]+#u', '-', $text);
        $text = trim($text, '-');
        if (function_exists('iconv')) $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
        $text = strtolower($text);
        $text = preg_replace('#[^-\w]+#', '', $text);
        if (empty($text)) return 'n-a';
        return $text;
    }

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->pageSector = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set pageTypesId
     *
     * @param integer $pageTypesId
     *
     * @return PageContent
     */
    public function setPageTypesId($pageTypesId)
    {
        $this->pageTypesId = $pageTypesId;

        return $this;
    }

    /**
     * Get pageTypesId
     *
     * @return integer 
     */
    public function getPageTypesId()
    {
        return $this->pageTypesId;
    }


    /**
     * Set pageName
     *
     * @param string $pageName
     *
     * @return PageContent
     */
    public function setPageName($pageName)
    {
        $this->pageName = $pageName;
        $this->setPageUrl($pageName);

        return $this;
    }

    /**
     * Get pageName
     *
     * @return string 
     */
    public function getPageName()
    {
        return $this->pageName;
    }

    /**
     * Set pageUrl
     *
     * @param string $pageUrl
     *
     * @return PageContent
     */
    public function setPageUrl($pageUrl)
    {
        $this->pageUrl = $this->slugify($pageUrl);

        return $this;
    }

    /**
     * Get pageUrl
     *
     * @return string 
     */
    public function getPageUrl()
    {
        return $this->pageUrl;
    }

    /**
     * Set richText
     *
     * @param string $richText
     *
     * @return PageContent
     */
    public function setRichText($richText)
    {
        $this->richText = $richText;

        return $this;
    }

    /**
     * Get richText
     *
     * @return string 
     */
    public function getRichText()
    {
        return $this->richText;
    }

    /**
     * Set pageTypes
     *
     * @param \acme\StyleGuideBundle\Entity\pageTypes $pageTypes the setter for page types
     *
     * @return PageContent
     */
    public function setPageTypes(\acme\StyleGuideBundle\Entity\pageTypes $pageTypes = null)
    {
        $this->pageTypes = $pageTypes;

        return $this;
    }

    /**
     * Get pageTypes
     *
     * @return \acme\StyleGuideBundle\Entity\pageTypes 
     */
    public function getPageTypes()
    {
        return $this->pageTypes;
    }

    /**
     * Add pageSector
     *
     * @param \acme\StyleGuideBundle\Entity\pageSector $pageSector
     *
     * @return PageContent
     */
    public function addPageSector(\acme\StyleGuideBundle\Entity\pageSector $pageSector)
    {
        $this->pageSector[] = $pageSector;

        return $this;
    }

    /**
     * Remove pageSector
     *
     * @param \acme\StyleGuideBundle\Entity\pageSector $pageSector
     *
     */
    public function removePageSector(\acme\StyleGuideBundle\Entity\pageSector $pageSector)
    {
        $this->pageSector->removeElement($pageSector);
    }

    /**
     * Get pageSector
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getPageSector()
    {
        return $this->pageSector;
    }

    /**
     * Set pageSectorId
     *
     * @param array $pageSectorId The id of the page sector
     *
     * @return PageContent
     */
    public function setPageSectorId($pageSectorId)
    {
        $this->pageSectorId = $pageSectorId;

        return $this;
    }

    /**
     * Get pageSectorId
     *
     * @return array 
     */
    public function getPageSectorId()
    {
        return $this->pageSectorId;
    }

    /**
     * Set PageParent
     *
     * @param \acme\StyleGuideBundle\Entity\PageParent $PageParent The parent page of this page
     *
     * @return PageContent
     */
    public function setPageParent(\acme\StyleGuideBundle\Entity\PageContent $PageParent = null)
    {
        $this->PageParent = $PageParent;

        return $this;
    }

    /**
     * Get PageParent
     *
     * @return \acme\StyleGuideBundle\Entity\PageParent 
     */
    public function getPageParent()
    {
        return $this->PageParent;
    }

}

以下是我尝试运行的查询:

$query = $this->getEntityManager()
            ->createQuery('
                SELECT p, s, c FROM acmeStyleGuideBundle:PageContent p
                JOIN p.pageSector s
                LEFT JOIN p.pageTypes t
                LEFT JOIN p.PageContent c
                WHERE p.pageUrl = :url
                AND s.sectorName = :sector
                AND c.PageParent = :parent
                AND t.typeName != :type'
            )
            ->setParameter('url', $pageUrl)
            ->setParameter('sector', $sector)
            ->setParameter('parent', $pageParent)
            ->setParameter('type', 'Section Headers');

这是我得到的错误。

  

[语义错误]第0行,第192行靠近'c':错误:类   acme \ StyleGuideBundle \ Entity \ PageContent没有名称的关联   PageContent

1 个答案:

答案 0 :(得分:1)

事实证明问题在于我的DQL语法:

 SELECT p, s, c FROM acmeStyleGuideBundle:PageContent p
                JOIN p.pageSector s
                LEFT JOIN p.pageTypes t
                LEFT JOIN p.PageContent c
                WHERE p.pageUrl = :url
                AND s.sectorName = :sector
                AND c.PageParent = :parent
                AND t.typeName != :type'

应该是

SELECT p, s, c FROM acmeStyleGuideBundle:PageContent p
                JOIN p.pageSector s
                LEFT JOIN p.pageTypes t
                LEFT JOIN p.PageParent c
                WHERE p.pageUrl = :url
                AND s.sectorName = :sector
                AND c.pageUrl = :parent
                AND t.typeName != :type'

我以为我正在加入桌子,但事实上我正在加入专栏。它现在完美无缺。