2015-10-26 3 views
0

У меня есть два объектаDoctrine2 manyToMany Inverse QueryBuilder

Product и Category

Product имеет (однонаправленный) поле manyToMany с Category с jointable имени product_has_category

я могу легко найти, какие Category имеет никакого Product но я не знаю, как получить обратный ...

Предположим, я хочу получить все Product для определенного Category в форме, это поле формы category, поэтому я не могу получить тип поля сущности с запросом Product, иначе он потерпит неудачу.

$form 
    ->add('category', 'entity', array(
     'class'  => 'AppBundle\Entity\Category', 
     'property' => 'name', 
     'query_builder' => function(EntityRepository $em) use ($product) { 
      return $em 
       ->createQueryBuilder('c') 
       ->innerJoin('AppBundle\Entity\Product', 'p', 'WITH', 'p.id = :product_id') 
       ->setParameter('product_id', $product->getId()) 
       ; 
     }, 
     'multiple' => true 
    )) 
; 

Конечно, это не сработает, но вы поняли, что я хочу делать. Поскольку Category не имеет отображаемого поля с Product (потому что это однонаправленное отображение), я не могу найти легкие продукты для печати ...

Средняя таблица не имеет сущности, потому что мы не имеем нужен он, это просто таблица mysql.

Запуск MySQL-запроса был бы таким простым, но нам нужно, чтобы он находился внутри QueryBuilder, потому что мы будем использовать его в формах.

SELECT c.name 
FROM category c 
INNER JOIN product_has_category pc ON pc.category_id = e.id 
INNER JOIN product p ON pc.product_id = p.id 
WHERE p.id = 10 
; 

Это, конечно, возвращает меня именно то, что я хочу, потому что на MySQL у меня есть доступ к средней таблице, так что я могу присоединиться все .. но, QueryBuilder? Я не знаю,

Я пробовал это, но я только что получил все замораживается (за 7М записей принес я думаю)

$em 
->createQueryBuilder('c') 
->select('c') 
->innerJoin('AppBundle\Entity\Product', 'p', 'WITH', '1 = 1') 
->innerJoin('p.categories', 'c') 
->where('p.id = :product_id') 
->setParameter('product_id', $product->getId()) 
; 

Я думаю, что это не дублируется, потому что другой вопрос не включает в себя QueryBuilder решение/вопрос, и некоторые люди могут быть смущены о том, как это сделать.

+0

Вы можете использовать «произвольный присоединиться к» http://stackoverflow.com/a/15444719 – jkavalik

+0

@jkavalik Но как я могу это сделать в QueryBuilder? Потому что это необработанный запрос. –

+1

В вашем коде 'p.id =: product_id' должно находиться в' where() ', ключевое слово' WITH' в DQL является эквивалентом 'ON' из соединения SQL. В противном случае QB - это просто инструмент, который поможет вам построить запрос динамически, но он использует все те же функции и синтаксис. Вы можете просто взять второй пример Ocramius и переписать его напрямую (или проверить его с помощью dql заранее - imho вы должны использовать только QB для динамических запросов, все остальное намного короче и читаемо как DQL) – jkavalik

ответ

0

Для thoose, которые муравьи знать, как сделать это внутри QueryBuilder, благодаря @jkavalik ответ ссылки на другой вопрос

Doctrine 2 DQL - how to select inverse side of unidirectional many-to-many query?

Это код, который я использовал, который работает как шарм.

$form 
    ->add('categories', 'entity', array(
     'class'  => 'AppBundle\Entity\Category', 
     'property' => 'name', 
     'query_builder' => function(EntityRepository $em) use ($product) { 
      return $em 
       ->createQueryBuilder('c1') 
       ->innerJoin('AppBundle\Entity\Product', 'p', 'WITH', '1 = 1') 
       ->innerJoin('p.equipments', 'c2') 
       ->where('p.id = :product_id') 
       ->andWhere('c1.id = c2.id') 
       ->setParameter('product_id', $product->getId()) 
      ; 
     } 
    )) 
; 
Смежные вопросы