Учение 2 обратное ЧЛЕН DQL - PullRequest
       30

Учение 2 обратное ЧЛЕН DQL

0 голосов
/ 15 февраля 2019

У меня есть Профиль класс с отношением ManyToMany "ссылки" и Ссылка класс.Мне нужно построить DQL-запрос, чтобы получить все ссылки для какого-либо профиля без обратного отношения (link-> profile).

Первой идеей было простое использование "MEMBER OF", но похоже на этоневозможно без прямого отношения.

MEMEBER OF строит подзапрос sql.Может быть, есть способ сделать что-то подобное?

Я не могу просто использовать

SELECT l FROM Profile p LEFT JOIN p.links l WHERE p.user = :user

, но я могу сделать:

SELECT e FROM Link WHERE e.id IN (SELECT l FROM Profile p LEFT JOIN p.links l WHERE p.user = :user)

, поэтому я сгенерировал этот SQL:

SELECT ... FROM Link t0_ 
   WHERE t0_.id IN (
      SELECT t1_.id FROM Profile a2_ 
      LEFT JOIN profile_link p3_ ON a2_.user_id = p3_.profile_user_id 
      LEFT JOIN Link t1_ ON t1_.id = p3_.link_id 
      WHERE a2_.user_id = ?
   )

есть ли способ построить подзапрос непосредственно к таблице profile_link без объединения профилей?

Что-то вроде:

SELECT ... FROM Link t0_ 
   WHERE t0_.id IN (
      SELECT l.link_id FROM profile_link l 
      WHERE l.profile_id = :user
   )

PS нет необходимости использовать таблицу профиля.

profile_link.profile_id = profile.user_id = user.id = :user

Мне нужен DQL-конструктор для построения более сложных запросов с поддержкой фильтра / сортировщика / группировщика.Я не могу использовать собственный запрос здесь или изменить класс Entity.Может быть, какая-то специальная функция DQL может решить эту проблему.

Ответы [ 2 ]

0 голосов
/ 19 марта 2019

Я сдаюсь.

Реализация ManyToMany - это простая пара реалий OneToMany, поэтому я создал класс для ее представления.

class ProfileLink{

    /** 
     * @ORM\Id
     * @ORM\OneToMany(targetEntity="Profile")
     */
    protected $profile;


    /** 
     * @ORM\Id
     * @ORM\OneToMany(targetEntity="Link")
     */
    protected $link;
}

Теперь я могу использовать DQL без обратной части на Ссылка Класс

SELECT p FROM ProfileLink LEFT JOIN p.link WHERE p.profile = :user_id;
0 голосов
/ 27 февраля 2019

Я полагаю, что вы переосмысливаете это.

Вы можете получить ссылки профиля сущности через определенное отношение ссылок .

Я предполагаю, что ваш класс профиля выглядит следующим образом:

use Doctrine\ORM\Mapping as ORM;

class Profile
{
    /**
     * @var integer
     *
     * @ORM\Column(name="user_id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
     private $id;

     /**
      * @ORM\ManyToMany(targetEntity="Link")
      * @ORM\JoinTable(name="profile_link",
      *      joinColumns={@ORM\JoinColumn(name="profile_user_id", referencedColumnName="user_id")},
      *      inverseJoinColumns={@ORM\JoinColumn(name="link_id", referencedColumnName="id")}
      *      )
      **/
     protected $links;

     public function getLinks()
     {
         return $this->links;
     }

Вы можете достичь того, что вы хотите, путем:

  • загрузки объекта профиля
  • получения связей отношения
  • прохождение через возвращенную коллекцию, которая в зависимости от режима извлечения отношений (нетерпеливый, ленивый или сверхленивый) приведет к извлечению сущностей, если они еще не извлечены из вышеприведенного шага.

В вашем контроллере просто выполните:

$profile = $em->getRepository('AppBundle\Entity\Profile')->find(1);
$links = $profile->getLinks();
foreach($links as $link) {
    echo $link->getId();
}

Таким образом, будут выполнены 2 запроса:

1) Извлечь строку профиля, например:

SELECT t0.user_id AS user_id_1 FROM profile t0 WHERE t0.user_id = ?

2) Чтобы получить связанные ссылки, например:

SELECT t0.id AS id_1 FROM link t0 INNER JOIN profile_link ON t0.id = profile_link.link_id WHERE profile_link.profile_user_id = ?

В последнем запросе присоединяется только таблица сопоставления , а не таблица профилей.Возвращенные строки не содержат данных профиля.

...