У меня есть класс Профиль с отношением 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 может решить эту проблему.





Я считаю, что вы слишком много думаете об этом.
Вы можете получить ссылки определенного Сущность профиля через связь ссылок.
Я предполагаю, что ваш класс 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 = ?
В последнем запросе присоединена только таблица сопоставления, а не таблица профилей. Возвращаемые строки не содержат данных профиля.
Я сдаюсь.
Реальность 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;
Спасибо за ответ, вы правы. Это правильные SQL-запросы, но мне нужна поддержка группировки/сортировки/разбиения на страницы, доступная только с помощью построителя запросов DQL. Поэтому я ищу решение DQL.