Доктрина 2 обратный ЧЛЕН DQL

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

Первая идея состояла в том, чтобы просто использовать «ЧЛЕН», но похоже, что это невозможно без прямого отношения.

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
   )

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
792
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я считаю, что вы слишком много думаете об этом.

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

Я предполагаю, что ваш класс Profile выглядит так:

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 = ?

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

Спасибо за ответ, вы правы. Это правильные SQL-запросы, но мне нужна поддержка группировки/сортировки/разбиения на страницы, доступная только с помощью построителя запросов DQL. Поэтому я ищу решение DQL.

El' 19.03.2019 04:27
Ответ принят как подходящий

Я сдаюсь.

Реальность 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;

Другие вопросы по теме