Учение подзапрос и везде

0

Я создаю большой фильтр if и where условий с помощью Doctrine.

Грубая идея выглядит примерно так:

$qb = $this->getEntityManager()->createQueryBuilder();

$qb->select(...)->from(...)->joins(...)

if ($params['param1']) {
  $qb->where(...)
}

if ($params['param2']) {
  $qb->andWhere(...)
}

if ($params['param3']) {
  $qb->andWhere(...)
}

Проблема, которую я ударил, заключается в том, что мне нужно использовать "andWhere" с "orWhere", но я хочу, чтобы "orWhere" сравнивался с этим одиночным "andWhere", а не со всем запросом, который я создал.

Так будет выглядеть примерно так:

if ($params['param4']) {
  $qb->andWhere(...)
    ->orWhere(...)
}

Если я сделаю так, как только я использую orWhere, он будет игнорировать все для param1, param2, param3, когда все, что я хочу, это сравнить его с param4s, где условие.

Я решил, что мне нужно использовать подзапрос, но я действительно потерял, как это сделать в Доктрине. Может ли кто-нибудь указать мне в правильном направлении, как это сделать?

  • 0
    Я рекомендую вам использовать andWhere вместо того, where при первом звонке. Это ничего не меняет для доктрины и позволяет избежать сброса ваших условий
Теги:
doctrine
doctrine2

1 ответ

4
Лучший ответ

В таких случаях вы можете полагаться на класс Expr который содержит методы, необходимые для создания более сложных запросов. Все, что вам нужно знать, описано в документации Doctrine в разделе Query Builder.

Текущая документация фактически дает пример, который почти соответствует указанному вами случаю использования. Вы могли бы написать что-то вроде этого, например:

$qb->andWhere($qb->expr()->orX(
   $qb->expr()->eq('u.id', '?1'),
   $qb->expr()->like('u.nickname', '?2')
));

Главное преимущество использования класса Expr заключается в том, что вы можете в значительной степени написать какую-либо комбинацию с ним, и для этого вы получите правильный DQL. Однако он может быть довольно подробным.

При этом вы также можете напрямую написать свое условие OR в andWhere:

$qb->andWhere('u.id = ?1 OR u.nickname = ?2');

Ещё вопросы

Сообщество Overcoder
Наверх
Меню