Você pode mapear um resultado de coluna única para um campo de entidade - veja consultas nativas e Mapeamento do conjunto de resultados Para alcançar isto. Como um exemplo simples:
use Doctrine\ORM\Query\ResultSetMapping;
$sql = '
SELECT p.*, COUNT(r.id)
FROM products p
LEFT JOIN reviews r ON p.id = r.product_id
';
$rsm = new ResultSetMapping;
$rsm->addEntityResult('AppBundle\Entity\Product', 'p');
$rsm->addFieldResult('p', 'COUNT(id)', 'reviewsCount');
$query = $this->getEntityManager()->createNativeQuery($sql, $rsm);
$results = $query->getResult();
Então, em sua entidade Product, você teria um
$reviewsCount
campo e a contagem seria mapeada para isso. Observe que isso só funcionará se você tiver uma coluna definida nos metadados do Doctrine, assim:/**
* @ORM\Column(type="integer")
*/
private $reviewsCount;
public function getReviewsCount()
{
return $this->reviewsCount;
}
Isto é o que é sugerido pelo Campos agregados Documentação da doutrina. O problema aqui é que você está essencialmente fazendo o Doctrine pensar que você tem outra coluna em seu banco de dados chamada
reviews_count
, que é o que você não quer. Portanto, isso ainda funcionará sem adicionar fisicamente essa coluna, mas se você executar um doctrine:schema:update
ele vai adicionar essa coluna para você. Infelizmente o Doctrine não permite propriedades virtuais, então outra solução seria escrever seu próprio hidratante personalizado, ou talvez assinar o loadClassMetadata
evento e adicione manualmente o mapeamento após o carregamento de sua entidade (ou entidades) específica. Observe que, se você fizer algo como
COUNT(r.id) AS reviewsCount
então você não pode mais usar COUNT(id)
em seu addFieldResult()
função e deve usar o alias reviewsCount
para esse segundo parâmetro. Você também pode usar o
ResultSetMappingBuilder
como um começo para usar o mapeamento do conjunto de resultados. Minha sugestão real é fazer isso manualmente em vez de passar por todas essas coisas extras. Essencialmente, crie uma consulta normal que retorne sua entidade e resultados escalares em uma matriz e, em seguida, defina o resultado escalar para um campo não mapeado correspondente em sua entidade e retorne a entidade.