Symfony:使用querybuilder构建连接两个表的选择选项

时间:2016-06-23 14:53:07

标签: php symfony doctrine-orm

在Symfony中,我有一个带有Select选项的表单,其中包含一些作者的书名,例如:

->add('title', EntityType::class, [
            'class' => 'AppBundle:Title',
            'choice_label' => 'fullTitle',
            'query_builder' => function (EntityRepository $er) {
                $queryBuilder = $er->createQueryBuilder('title');
                $queryBuilder
                    ->select('title')
                    ->innerJoin('title.author', 'author')
                    ->addOrderBy('author.name', 'ASC')
                    ->addOrderBy('title.title', 'ASC');

                return $queryBuilder;
            },
            'label' => 'fields.title.title'
        ])

我想以这种方式显示作者姓名和标题名称:“作者>标题”。我设法通过使用“fullTitle”选项标签和标题实体中的这个黑客来实现:

public function getFullTitle()
{
    return $this->getAuthor()->getSurname() . ',  ' . $this->getAuthor()->getName() . ' > ' . $this->getTitle();
}

但这在很多方面都非常糟糕,特别是对于表现而言。 所以我尝试使用CONCAT在查询中构建“Author> Title”字符串,但似乎无法使用查询构建器完成。

我检查了文档,所有示例都是关于一个实体,没有连接。

提前致谢:)

2 个答案:

答案 0 :(得分:2)

您必须同时选择titleauthor,否则author仍将通过延迟加载加载。添加->addSelect('author')就足够了。

答案 1 :(得分:0)

如果要优化数据加载,可以在查询构建器中使用包含所需信息的部分请求,并使用闭包构建标签而不修改实体

    ->add('title', EntityType::class, [
        'class' => 'AppBundle:Title',
        'choice_label'  => function ($entity) {
             return $entity->getAuthor()->getSurname() . ',  ' .
                    $entity->getAuthor()->getName() . ' > ' . 
                    $entity->getTitle();
         },
        'query_builder' => function (EntityRepository $er) {
            $queryBuilder = $er->createQueryBuilder('title');
            $queryBuilder
                ->select('partial title.{id, title}')
                ->addSelect('partial author.{id, surname, name}')
                ->innerJoin('title.author', 'author')
                ->addOrderBy('author.name', 'ASC')
                ->addOrderBy('title.title', 'ASC');

            return $queryBuilder;
        },
        'label' => 'fields.title.title'
    ])

我不认为EntityType可以像CONCAT一样管理标量结果,因为对象水分器用于获取实体。

祝你好运