Doctrine DQL到QueryBuilder

时间:2014-12-14 14:20:01

标签: mysql symfony doctrine-orm dql

也许有人可以帮我转变

我正在尝试通过page_id获取与FaqPageQuestionContent无关的QuestionContent,并在选择框中查看

SELECT q FROM VswSystemCmsBundle:QuestionContent q WHERE q.id NOT IN
        (SELECT fq.questioncontent_id FROM VswSystemCmsBundle:FaqPageQuestionContent fq WHERE fq.faqcontentpage_id = :page_id) 

进入QueryBuilder表单以在Sf2表单中使用它。

3 个答案:

答案 0 :(得分:2)

像这样的东西(未经测试,可能是字段名称错误,纠正它们):

$subQueryBuilder = $this->getEntityManager()->createQueryBuilder();
$subQuery = $subQueryBuilder
    ->select(['fq.questioncontentId'])
    ->from('VswSystemCmsBundle:FaqPageQuestionContent', 'fq')
    ->where('fq.faq = :faq')
    ->setParameter('faq', $faq)
;

$queryBuilder = $this->getEntityManager()->createQueryBuilder();
$query = $queryBuilder
    ->select(['q'])
    ->from('VswSystemCmsBundle:QuestionContent', 'q')
    ->where($queryBuilder->expr()->notIn('q.id', $subQuery->getDQL()))
    ->getQuery()
;

return $query->getResult();

答案 1 :(得分:2)

现在您澄清了您想要做的事情,我建议您使用'实体'表单上连接到QuestionContent实体的字段类型。

// don't forget the use statement for your repository up top
use Your\VswSystemCmsBundle\Repository\QuestionContentRepository;

// in buildForm() (this assumes you have $pageId set properly)
$builder
    ->add('questionContent', 'entity', array(
        'class'         => 'VswSystemCmsBundle:QuestionContent',
        'property'      => 'questionForForm',
        'query_builder' => function(QuestionContentRepository $repo) use ($pageId) { 
            return $repo->findNotAttachedQuestions($pageId);
        },
    ))
;

编辑:将您的QueryBuilder放在该实体的存储库中,然后从那里调用它。

// this is Your\VswSystemCmsBundle\Repository\QuestionContentRepository class
public function findNotAttachedQuestions($pageId)
{
    $subQuery = $this->createQuery("
            SELECT  fq.questioncontent_id 
            FROM    VswSystemCmsBundle:FaqPageQuestionContent fq
            WHERE   fq.faqcontentpage_id = :page_id
        ")
        ->setParameter('page_id', $pageId)
    ;

    return $this->createQueryBuilder('q')
        ->where($qb->expr()->notIn('q.id', $subQuery))
    ;
}

注意我如何定义'属性'以上是questionForForm?我们需要在QuestionContent实体中添加一个getter函数,它返回问题的前30个字符。

// this is Your\VswSystemCmsBundle\Entity\QuestionContent class
public function getQuestionForForm()
{
    return substr($this->getQuestion(), 0, 30);
}

现在一切都在正确的地方分开了。您不必担心将DQL转换为Doctrine QueryBuilder实例,因为您将其存储在Repository中并在那里调用它。您不必创建自定义数组来返回选择的数据,现在您可以使用可重用的函数直接从实体返回问题的前30个字符。

答案 2 :(得分:1)

嗯,我想我会更好地在表格类中使用DQL +这样的东西,如果形式'则选择' => $这 - > getNotAttachedQuestions($ builder->的getData() - >的getId()),

public function getNotAttachedQuestions($pageId)
{
    $questions = $this->getQuestionRepo()->getNotAttachedQuestions($pageId);
    $select = [];
    foreach ($questions as $question) {
        $select[$question->getId()] = substr($question->getQuestion(),0,30);
    }

    return $select;
}