2016-09-12 3 views
0

У меня есть один-ко-многим, однонаправленный с отношениями Join Table в приложении Symfony, который мне нужно запросить, и я не могу понять, как это сделать в DQL или Query Builder.Symfony One-To-Many, однонаправленный с запросом Join Table

Объект Like не имеет собственного свойства комментариев, поскольку он может принадлежать множеству различных типов объектов.

В основном я должен был бы перевести что-то вроде этого:

SELECT likes 
FROM AppBundle:Standard\Like likes 
INNER JOIN comment_like ON comment_like.like_id = likes.id 
INNER JOIN comments ON comment_like.comment_id = comments.id 
WHERE likes.created_by = :user_id 
AND likes.active = 1 
AND comments.id = :comment_id 

Я уже пробовал это, но присоединиться вывод некорректный, он выбирает любой активный, и независимо от его ассоциации с данным комментарием

 $this->createQueryBuilder('l') 
     ->select('l') 
     ->innerJoin('AppBundle:Standard\Comment', 'c') 
     ->where('l.owner = :user') 
     ->andWhere('c = :comment') 
     ->andWhere('l.active = 1') 
     ->setParameter('user', $user) 
     ->setParameter('comment', $comment) 

ответ

0

Я нашел документацию по Symfony очень плохой относительно однонаправленных запросов. В любом случае, я получил его, используя DQL и sub-select на собственном объекте, что, конечно же, не так быстро. Любое предложение о том, как улучшить это, более чем приветствуется!

$em = $this->getEntityManager(); 
$query = $em->createQuery(' 
    SELECT l 
    FROM AppBundle:Standard\Like l 
    WHERE l.id IN (
     SELECT l2.id 
     FROM AppBundle:Standard\Comment c 
     JOIN c.likes l2 
     WHERE c = :comment 
     AND l2.owner = :user 
     AND l2.active = 1 
    )' 
) 
->setParameter('user', $user) 
->setParameter('comment', $comment) 
; 
1

Я вижу 2 варианта решения этой проблемы:

  1. Сделать отношение двунаправленным
  2. Использование SQL (родной запрос) + ResultSetMapping.

Для последнего варианта, здесь приведен пример метода репозитория (только что проверил, что он работает):

public function getLikes(Comment $comment, $user) 
{ 
    $sql = ' 
     SELECT l.id, l.active, l.owner 
     FROM `like` l 
     INNER JOIN comment_like ON l.id = comment_like.like_id 
     WHERE comment_like.comment_id = :comment_id 
      AND l.active = 1 
      AND l.owner = :user_id 
    '; 
    $rsm = new \Doctrine\ORM\Query\ResultSetMappingBuilder($this->_em); 
    $rsm->addRootEntityFromClassMetadata(Like::class, 'l'); 

    return $this->_em->createNativeQuery($sql, $rsm) 
     ->setParameter('comment_id', $comment->getId()) 
     ->setParameter('user_id', $user) 
     ->getResult(); 
} 

PS: В случае Mysql, «как» зарезервировано слово. Итак, если кто-то хочет иметь таблицу с именем «like» - просто имя окружения с обратными выводами по определению:

* @ORM\Table(name="`like`")