Хорошо, вот в чем проблема.
У меня есть сущность с именем HelpDocuments и сущность с именем LogEntry.
HelpDocuments может быть отклонен пользователем. Когда это происходит, я создаю LogEntry со следующими атрибутами:
- событие - например: helpDocument.dismiss
- entity_id - например: 11
- entityDiscriminator - например: HelpDocument
Между HelpDocument и LogEntry не создается никаких отношений, поскольку я реализую свою собственную логику дискриминатора.
Итак, я пытаюсь получить запрос на все документы HelpDocuments, которые не были отклонены. Я могу сделать это с помощью sql, левое внешнее соединение подзапроса следующим образом:
SELECT HelpDocument.*, temp.*
FROM HelpDocument
LEFT OUTER JOIN(
SELECT LogEntry.entity_id
FROM LogEntry
WHERE LogEntry.entityDiscriminator = 'HelpDocument'
AND LogEntry.event = 'helpDocument.dismiss'
AND LogEntry.entity_id = 11
) as temp ON HelpDocument.id = temp.entity_id
WHERE temp.entity_id IS NULL;
Моя проблема в том, как мне превратить это в DQL, учитывая, что отношения не определены?
Обновленное решение:
Таким образом, решение заключалось в том, чтобы не использовать LEFT OUTER JOIN, потому что они не существуют / не имеют смысла в Doctrine2. В конце концов, мне пришлось выполнить соединение подзапроса:
/**
* Filter by User Dismissed
*
* @param $qb
* @param $route
* @return mixed
*/
public function filterQueryByUserDismissed(QueryBuilder $qb, $args)
{
$args = array_merge(array(
"user" => null,
"dismissed" => false
), $args);
/** @var $dismissedQB QueryBuilder */
$dismissedQB = $this->_em->createQueryBuilder();
/*
This line is important. We select an alternative attribute rather than
letting Doctrine select le.id
*/
$dismissedQB->select('le.entityId')
->from('\Mlf\AppBundle\Entity\UserEntityEventLog', 'le')
->where('le.entityDiscriminator = :entityDiscriminator')
->andWhere('le.event = :event')
->andWhere('le.user = :userId');
$function = (true === $args['dismissed']) ? "in" : "notIn";
$expr = $qb->expr()->$function($this->classAlias.'.id', $dismissedQB->getDQL());
/** @var $qb QueryBuilder */
$qb->andWhere($expr)
->setParameter("entityDiscriminator", HelpDocument::getDiscriminator())
->setParameter("event", HelpDocumentEvents::HELPDOCUMENT_DISMISS)
->setParameter("userId", $args["user"]);
// exit($result = $qb->getQuery()->getSQL());
return $qb;
}
Этот запрос DQL приводит к следующему SQL:
SELECT h0_.id AS id0
FROM HelpDocument h0_
WHERE (
h0_.id NOT IN (
SELECT l1_.entity_id
FROM LogEntry l1_
WHERE l1_.entityDiscriminator = 'helpDocument'
AND l1_.event = 'helpDocument.dismiss'
AND l1_.user_id = 1
)
)
Ура!