【问题标题】:Doctrine oneToMany - querying for oneDoctrine oneToMany - 查询一个
【发布时间】:2013-02-01 17:18:52
【问题描述】:

我有一个一对多的关系,其中一个页面有多个版本。

**page**

id
parent_id

**page_version**
id
page_id
title
published
date

这些由外键 page_id 关联。所以我有一个 Page 实体和一个 PageVersion 实体:

class Page
{
    /**
    * @ORM\OneToMany(targetEntity="PageVersion", mappedBy="page")
    */
   private $pageversions;
}
class PageVersion
{
    /**
     * @var page
     *
     * @ORM\ManyToOne(targetEntity="Page", inversedBy="pageversions")
     *
     */
    private $page;

}

所以我可以获得每个页面的所有页面版本。但是,每个页面都只会有一个已发布的页面版本。因此,在查询时如何获取最新版本?即 Where published = '1' 而不是获取所有版本的列表?

这是我的查询示例:

public function findAllPages()
{
    $query = $this->getEntityManager()
        ->createQuery('
        SELECT DISTINCT p,v
        FROM XYZWebsiteBundle:Page p
        JOIN p.pageversions v
        WHERE v.published = :published
        AND v.deleted = :deleted'
    )->setParameters(array('published' => 1, 'deleted' => 0));

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

但是,如果我遍历结果,我只能访问 Page 属性而不是 PageVersion 属性,例如标题、发布、日期等。

$entities = $em->getRepository('XYZWebsiteBundle:Page')->findAllPages();

    foreach($entities as $entity){
        print($entity->getPageVersion()->getTitle());
    }

返回的错误是 Fatal error: Call to undefined method Doctrine\ORM\PersistentCollection::getTitle()。

【问题讨论】:

    标签: symfony doctrine relationship one-to-many


    【解决方案1】:
    $er = $this->getDoctrine()->getRepository('XYZWebsiteBundle:Page');
    $qb = $er->createQueryBuilder('p')
        ->where('p.published = :published')
                    ->setParameter('published', 1)
        ;
    
    $entities=$qb->getQuery()->getResult();
    

    如果您确定发布状态的页面不会超过 1 个,您甚至可以使用 getOneOrNullResult() 代替 getResult()。如果没有匹配的实体则返回 null,如果有一个匹配则返回实体,如果有多个则返回异常。

    编辑:好的,所以您必须在 PageVersion 而不是页面上构建查询。试试:

     $er = $this->getDoctrine()->getRepository('XYZWebsiteBundle:PageVersion');
        $qb = $er->createQueryBuilder('p')
            ->where('p.page = :page')
                        ->setParameter('page', $page)
            ->andWhere('p.published = :published')
                        ->setParameter('published', 1)
            ;
    
        $pageVersion=$qb->getQuery()->getResult();
    

    $page 是您尝试为其查找已发布版本的页面。

    【讨论】:

    • 谢谢。我试过了,但出现以下错误:[Semantical Error] line 0, col 54 near 'published = ': Error: Class XYZ\WebsiteBundle\Entity\Page has no field or association named published FYI The published field is inside page_version而不是页面那么我如何从查询中引用它?
    • 谢谢。为了给你更多信息,我在我的 CMS 中有一个页面列表,管理员用户可以在其中添加/编辑/删除等。所以如果我有一个 listAction 我想列出所有页面,我只需运行一个查询来获取所有页面实体(因为此时版本无关紧要),那么当我希望编辑该页面时,在 editAction 中我会运行您的第二个查询以获取最新版本(其中已发布 = 1)?这样我就可以拉入最新版本的数据并进行编辑。
    • 其实我最初查询页面时确实需要最新版本,因为我需要显示页面的标题。因此,在查询页面实体时,我还需要获取最新的页面版本,以便在列表中提取最新的标题。因此,我需要查询页面但加入 page_version where published = 1 然后我可以遍历每个页面并拉出最新的标题。希望这是有道理的?
    • 在继续之前,请告诉我我提出的第二个查询是否有效?
    • 是的,它可以获取一个特定页面的所有页面版本。但是,我也在尝试获取所有页面的列表,其中每个页面都有最新的页面版本。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    相关资源
    最近更新 更多