Możesz zmapować wynik w jednej kolumnie do pola encji - spójrz na zapytania natywne i ResultSetMapping osiągnąć to. Jako prosty przykład:
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();
Następnie w jednostce Produkt miałbyś $reviewsCount
pole i licznik zostanie do niego zmapowany. Zauważ, że zadziała to tylko wtedy, gdy masz zdefiniowaną kolumnę w metadanych Doctrine, na przykład:
/**
* @ORM\Column(type="integer")
*/
private $reviewsCount;
public function getReviewsCount()
{
return $this->reviewsCount;
}
Tak sugeruje Pola agregacji
Dokumentacja doktrynalna. Problem polega na tym, że zasadniczo sprawiasz, że Doctrine myśli, że masz inną kolumnę w swojej bazie danych o nazwie reviews_count
, czego nie chcesz. Tak więc będzie to nadal działać bez fizycznego dodawania tej kolumny, ale jeśli kiedykolwiek uruchomisz doctrine:schema:update
doda tę kolumnę za ciebie. Niestety Doctrine tak naprawdę nie zezwala na wirtualne właściwości, więc innym rozwiązaniem byłoby napisanie własnego niestandardowego hydratora lub być może zasubskrybowanie loadClassMetadata
zdarzenia i ręcznie dodaj mapowanie po załadowaniu konkretnej jednostki (lub jednostek).
Pamiętaj, że jeśli zrobisz coś takiego jak COUNT(r.id) AS reviewsCount
wtedy nie możesz już używać COUNT(id)
w twoim addFieldResult()
funkcji i zamiast tego należy użyć aliasu reviewsCount
dla tego drugiego parametru.
Możesz również użyć ResultSetMappingBuilder
jako początek korzystania z mapowania zbioru wyników.
Moja aktualna sugestia to zrobić to ręcznie, zamiast przechodzić przez wszystkie te dodatkowe rzeczy. Zasadniczo utwórz normalne zapytanie, które zwraca zarówno twoją encję, jak i wyniki skalarne w tablicy, a następnie ustaw wynik skalarny na odpowiadające, niezmapowane pole w twojej encji i zwróć encję.