Есть ли правильный путь в Доктрине, чтобы вкладывать «ИЛИ» в предложения? - PullRequest
0 голосов
/ 01 июня 2018

У меня есть запрос, который вытягивает некоторые задания, если они имеют дату окончания и не завершены, что дает желаемый результат:

реальный код

$this->createQueryBuilder('j')
                ->where('j.completed = :false OR j.completed is NULL')
                ->andWhere('j.has_due_date = :true')
                ->andWhere('j.has_due_date = :true')
                ->setParameters( array(
                    'false' => FALSE,
                    'true' => TRUE
                ) )
                ->orderBy('j.due_date', 'asc')
                ->getQuery();

результат

SELECT j FROM App\Entity\Jobs j 
    WHERE (
        j.completed = :false 
        OR j.completed is NULL
    ) 
    AND j.has_due_date = :true 
    ORDER BY j.due_date ASC

Я хочу следовать передовой практике DQL для этого и чувствую, что есть другой способ или написание этого и только одно предложение WHERE на вызовна ->where варианте (andWhere(), orWhere())

На мой взгляд, это что-то вроде этого, но я не могу найти ничего, чтобы подтвердить это:

псевдокод

$query = $this->createQueryBuilder('j')
                  ->where( $requiredClass->
                                ->where('j.completed = :false')
                                ->orWhere('j.completed is NULL')
                                ->setParameter('false', FALSE) 
                  )
                  ->andWhere('j.has_due_date = :true')
                  ->setParameter('true', TRUE) 
                  ->orderBy('j.due_date', 'asc')
                  ->getQuery();

Основные вопросы:

  • Есть ли способ сделать это вторым способом?
  • Излишне усложняю ли я вещи?
  • если есть второй способ сделать это, как упомянуто, первое утверждение работает так, почему это должно иметь значение?

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Использование построителя запросов должно быть проще и понятнее

    public function someFunction()
    {
        $qb = $this->createQueryBuilder('j');

        $orX = $qb->expr()->orX();
        $andX = $qb->expr()->andX();

        $orX->add($qb->expr()->eq('j.completed', $qb->expr()->literal(false)));
        $orX->add($qb->expr()->isNull('j.completed'));

        $andX->add($qb->expr()->eq('j.has_due_date', $qb->expr()->literal(true)));

        $qb->andWhere($orX, $andX)
            ->orderBy('j.due_date', 'asc')
            ->getQuery()
            ->getResult();
    }
0 голосов
/ 01 июня 2018

Как указано в официальной документации для QueryBuilder передового опыта - правильный способ - использовать вспомогательный метод QueryBuilder::expr(), а также вспомогательный класс Doctrine\ORM\Query\Expr. Методы API высокого уровня

, т.е.:

// create QueryBuilder
$qb = $this->createQueryBuilder('j');

// build conditions
$qb->where(
    $qb->expr()->orX(
        $qb->expr()->eq('j.completed', ':false'),
        $qb->expr()->isNull('j.completed')
    )
)
->andWhere(
    $qb->expr()->eq('j.has_due_date', ':true')
)
->andWhere(
    $qb->expr()->eq('j.has_due_date', ':true')
)
->setParameters(array(
    'false' => FALSE,
    'true' => TRUE
))
->orderBy('j.due_date', 'asc');

// get query
$query = $qb->getQuery();

// execute and get result
$result = $query->getResult();
...