DQL для этого оператора SQL в Doctrine2 с отношением ManyToMany

Я сделал этот запрос SQL, чтобы получить нужные мне данные из БД, и он работает именно так, как я хочу:

SELECT DISTINCT ofreg.nombre as oficina
FROM nomencladores.oficina_regional AS ofreg
LEFT JOIN negocio.solicitud_usuario_oficina_regional AS solusofreg
ON (ofreg.id = solusofreg.oficina_regional_id)
JOIN nomencladores.tipo_tramite tram
ON (tram.id = solusofreg.tipo_tramite_id)
WHERE (tram.id = 1);

Так как мои отношения не будут генерировать никаких дополнительных полей в третьей таблице, тогда я решу перейти к надлежащим аннотациям для моих сущностей, посмотрите:

class TipoTramite
{
use IdentifierAutogeneratedEntityTrait;
use NamedEntityTrait;
use ActiveEntityTrait;

/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\OficinaRegional", inversedBy="tipoTramites", cascade={"persist"})
* @ORM\JoinTable(name="negocio.solicitud_usuario_oficina_regional", schema="negocio",
*      joinColumns={@ORM\JoinColumn(name="oficina_regional_id", referencedColumnName="id")},
*      inverseJoinColumns={@ORM\JoinColumn(name="tipo_tramite_id", referencedColumnName="id")}
* )
*/
protected $oficinaRegionals;
}

class OficinaRegional
{
use IdentifierAutogeneratedEntityTrait;
use NamedEntityTrait;
use ActiveEntityTrait;

/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\TipoTramite", mappedBy="oficinaRegionals", cascade={"persist"})
*/
protected $tipoTramites;
}

Имея эти сущности и предполагая, что они правы (поправьте меня, если я ошибаюсь), мне нужно написать DQL, который удовлетворяет приведенному выше коду SQL, может ли кто-нибудь помочь мне в написании этого DQL?

Я всегда делал это, имея посредника, но этот случай для меня совершенно новый. Как и вдобавок я знаю обходной путь и буду создавать view на уровне БД и написать сущность только для этого представления с не set метод просто get методы с тех пор будут доступны только для чтения, но я не знаю, является ли правильный путь, и мне действительно нравится узнавать, как сделать это, используя ManyToMany (в моем проекте у меня много связей этого типа, так что я уверен, что понадобится эта помощь позже в ближайшее время).

ОБНОВИТЬ

Хорошо, я бы хотел оставить этот след на этой проблеме, и я делал некоторые тесты, но без какого-либо полезного результата, вот мои попытки:

Первый подход

public function filtrarOficinaRegionalPorTramite($tramite)
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb
->select('ofr.nombre AS oficinaRegional, ttr.nombre as tipoTramite')
->from("AppBundle:OficinaRegional", "ofr")
->where("ofr.activo = :activo")
->leftJoin("AppBundle:TipoTramite", "ttr");

$qb->setParameter('activo', TRUE);

if ($tramite != NULL) {
$qb->andWhere('ttr.id = :tramite');
$qb->setParameter('tramite', $tramite);
}

echo $qb->getQuery()->getSQL();
return $qb->getQuery()->getResult();
}

Не сработало, так как результат SQL из предыдущего кода такой:

SELECT n0_.nombre AS nombre0, n1_.nombre AS nombre1
FROM nomencladores.oficina_regional n0_
LEFT JOIN nomencladores.tipo_tramite n1_
ON (n0_.activo = ?)

Второй подход

public function filtrarOficinaRegionalPorTramite($tramite)
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb
->select('ofr.nombre AS oficinaRegional, ttr.nombre as tipoTramite')
->from("OficinaRegional ofr")
->where("ofr.activo = :activo")
->leftJoin('ofr.TipoTramite ttr');

$qb->setParameter('tramite', $tramite);

if ($tramite != NULL) {
$qb->where('ttr.id = :tramite');
$qb->setParameter('tramite', $tramite);
}

return $qb->getQuery()->getResult();
}

Но получил эту ошибку:

Предупреждение: отсутствует аргумент 2 для Doctrine \ ORM \ QueryBuilder :: from (),
называется в
/var/www/html/project.dev/src/AppBundle/Entity/Repository/RegionalOfficeRepository.php
в строке 25 и определяется в
/var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php
строка 721

Третий подход

После того, как я потратил огромное количество времени, пытаясь заставить вещи работать, у меня все еще есть проблемы, но на этот раз я ближе к их решению. Итак, вот мой последний снимок с этим кодом:

public function filtrarOficinaRegionalPorTramite($tramite)
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb
->select('ofr.nombre AS oficinaRegional, ttr.nombre as tipoTramite')
->distinct()
->from("AppBundle:OficinaRegional", "ofr")
->where("ofr.activo = :activo")
->leftJoin("ofr.tipoTramites", "ttr");

$qb->setParameter("tramite", $tramite);

if ($tramite != NULL) {
$qb->andWhere("ttr.id = :tramite");
$qb->setParameter("tramite", $tramite);
}

echo $qb->getQuery()->getSQL();
return $qb->getQuery()->getResult();
}

Я получил этот SQL:

SELECT DISTINCT n0_.nombre AS nombre0,
n1_.nombre AS nombre1
FROM nomencladores.oficina_regional n0_
LEFT JOIN negocio.solicitud_usuario_oficina_regional n2_ ON n0_.id = n2_.tipo_tramite_id
LEFT JOIN nomencladores.tipo_tramite n1_ ON n1_.id = n2_.oficina_regional_id
WHERE n0_.activo = ?
AND n1_.id = ?;

Что совсем не так, но вот каким должен быть окончательный SQL:

SELECT DISTINCT n0_.nombre AS nombre0,
n1_.nombre AS nombre1
FROM nomencladores.oficina_regional n0_
LEFT JOIN negocio.solicitud_usuario_oficina_regional n2_ ON n0_.id = n2_.oficina_regional_id
LEFT JOIN nomencladores.tipo_tramite n1_ ON n1_.id = n2_.tipo_tramite_id
WHERE n0_.activo = TRUE
AND n1_.id = 1;

Что я делаю не так?

0

Решение

Похоже, что ваши сопоставления столбцов соединения некорректны для TipoTramite, попробуйте перевернуть их.

 /**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\OficinaRegional", inversedBy="tipoTramites", cascade={"persist"})
* @ORM\JoinTable(name="negocio.solicitud_usuario_oficina_regional", schema="negocio",
*      joinColumns={@ORM\JoinColumn(name="tipo_tramite_id", referencedColumnName="id")},
*      inverseJoinColumns={@ORM\JoinColumn(name="oficina_regional_id", referencedColumnName="id")}
* )
*/

http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-unidirectional-with-join-table

Что касается вопросительных знаков, то это просто параметры, которые будут заполнены позже.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]