Подтвердить что ты не робот

Doctrine2: Полиморфные запросы: поиск по свойствам подклассов

У меня есть проект, где я занимаюсь заказами клиентов. Некоторые из этих заказов осуществляются через Amazon.com. Таким образом, у меня есть объект Order и объект AmazonOrder, который его расширяет. Одна вещь, добавленная AmazonOrder, - это AmazonOrderId.

У меня есть требование реализовать широкую функцию поиска. Пользователь может вводить некоторые вещи в текстовое поле и использоваться в кучке выражений в одном большом where-clause. Так, например, если пользователь искал "111", результаты включают в себя любые заказы с идентификатором, начиная с 111, причем любой заказ отправляется в почтовые индексы, начинающиеся с 111, причем любой заказ отправляется на "111 Main St" и т.д..

Этот материал реализован с запросом, созданным запросом-построением, с большим выражением orX().

Теперь я хотел бы сопоставлять все заказы, но если они являются AmazonOrder, также совпадают с AmazonOrderId.

И я застрял - я подозреваю, что это будет невозможно

Вот как я создаю запрос:

$qb->select('o,s')->from('PMS\Entity\Order', 'o');    
$qb->leftJoin('o.shippingInfo','s');
$qb->andWhere('o.status = :status');
$qb->setParameter('status',$status);
$qb->andWhere(
    $qb->expr()->orX(
        $qb->expr()->like('o.id',':query')
        $qb->expr()->like('s.address',':query')
        $qb->expr()->like('s.city',':query')
    )
);
$qb->setParameter('query',$userQuery .'%');

$orders = $qb->getQuery()->getResult();

И я не могу понять, как добавить условие, которое говорит грубо: "ИЛИ (Заказ - это AmazonOrder AND AmazonOrderId LIKE" $userQuery% ') "

У кого-нибудь есть понимание? Либо способ справиться с этим, либо, по крайней мере, подтвердить, что это невозможно сделать таким образом?

4b9b3361

Ответ 1

Здесь другое решение, которое работает для меня с Doctrine 2.4:

$qb->select('o')
   ->from('Order', 'o')
   ->leftJoin('AmazonOrder', 'ao', 'WITH', 'o.id = ao.id')
   ->andWhere('o.id like :query or ao.amazonOrderId like :query')
   ->setParameter('query', $someQuery);

Вы только что ушли - присоединитесь к сущности в конкретном подклассе. (Вы можете адаптировать мой простой запрос к вашему прецеденту.)

Я пробовал это ровно один раз, но, похоже, он работает.

Ответ 2

Хм, у меня были похожие проблемы в моем последнем проекте доктрины.

Одно время это было всего лишь одно поле, поэтому я переместил его в родительский класс - не самое приятное решение, но работал. В другом случае там, где слишком много свойств, чтобы они загромождали родительский класс. Я выполнил собственный SQL-запрос для поиска и получения идентификаторов записей, а затем использовал WHERE IN (...) dql для извлечения сущностей.

Компромисс может быть доктриной ResultSetMapping, которая может напрямую сопоставить собственный SQL-запрос с объектами, хотя каждый раз, когда я работал с ним, я нашел его довольно неуклюжим в использовании и накладными расходами для двух запросов (выборки ids и fetch entites), как указано выше, чтобы быть пренебрежимым.

Возможно, вы могли бы выполнить что-то с оператором INSTANCEOF в своем предложении WHERE, хотя я не думаю, что доктрина будет достаточно умна, чтобы распознать ее так, как вы хотите.