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

Symfony2 QueryBuilder присоединяется к ON и WITH разности

Я новичок в Symfony2, и я успешно с успехом построил QueryBuilder и Doctrine 2. Вероятно, это глупый вопрос, но как в режиме онлайн, так и в методах Symfony2 мне не удалось найти ничего для понимания разницы между предложениями WITH WITH и "ON".

Например, это мой код соединения:

->leftJoin('EcommerceProductBundle:ProductData', 'pdata', 'WITH', 'prod.id = IDENTITY(pdata.product)')

Он работает хорошо, но если я помещаю ON вместо WITH, я получаю следующую ошибку:

[Синтаксическая ошибка] строка 0, col 200: Ошибка: ожидается Doctrine\ORM\Query\Lexer:: T_WITH, получил 'ON'

Почему? Я видел среди объектов, что есть как T_ON, так и T_WITH, такие как предложения о присоединении, но какова их разница в использовании? Каково их использование?

4b9b3361

Ответ 1

@florian дал вам правильный ответ, но позвольте мне попытаться объяснить это на примере:

В sql объединения выполняются следующим образом:

SELECT * FROM category
    LEFT JOIN product ON product.category_id = category.id

(или что-то вроде этого)

Теперь в Доктрине вам не нужно использовать предложение ON, потому что доктрина знает это из аннотаций отношений в ваших сущностях. Таким образом, пример выше:

// CategoryRepository.php
public function getCategoriesAndJoinProducts() 
{
    return $this->createQueryBuilder("o")
        ->leftJoin("o.products", "p")->addSelect("p") 
        ->getQuery()->getResult() ;
}

Оба получат все категории и присоединяют к ним связанные с ними продукты.

Теперь появляется предложение WITH. Если вы хотите присоединиться только к продуктам с ценой более 50, вы бы сделали это в SQL:

SELECT * FROM category
    LEFT JOIN product ON product.category_id = category.id AND product.price>50

В Доктрине:

// CategoryRepository.php
public function getCategoriesAndJoinProductsWithPriceBiggerThan($price) 
{
    return $this->createQueryBuilder("o")
        ->leftJoin("o.products", "p", "WITH", "p.price>:price")
            ->setParameter("price", price)->addSelect("p") 
        ->getQuery()->getResult() ;
}

Итак, на самом деле вы никогда не должны использовать ON, если используете Doctrine. Если у вас есть что-то в этом роде, вы можете быть почти уверены, что вы ввернули что-то еще.

Ответ 2

В теории ON позволяет вам дать полные критерии присоединения, в то время как WITH разрешает добавлять дополнительные критерии к значениям по умолчанию (IMHO).

Но то, что позволяет DQL, заключается в том, чтобы избежать предоставления критериев JOIN:

Вы просто должны сказать: $qb->leftJoin('prod.pdata', 'pdata');

И doctrine2 правильно обработает соединение.

Вот связанный с этим вопрос: Могу ли я использовать ключевое слово "ON" в DQL или мне нужно использовать Native Query?