Můžete namapovat výsledek jednoho sloupce do pole entity – podívejte se na nativní dotazy a ResultSetMapping dosáhnout toho. Jako jednoduchý příklad:
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();
Pak byste v entitě produktu měli $reviewsCount
pole a počet by byl mapován k tomu. Všimněte si, že to bude fungovat pouze v případě, že máte sloupec definovaný v metadatech Doctrine, například takto:
/**
* @ORM\Column(type="integer")
*/
private $reviewsCount;
public function getReviewsCount()
{
return $this->reviewsCount;
}
To je to, co navrhuje Souhrnná pole
Dokumentace doktríny. Problém je v tom, že v podstatě nutíte Doctrine myslet si, že máte ve své databázi další sloupec s názvem reviews_count
, což je to, co nechcete. Takže to bude stále fungovat bez fyzického přidání tohoto sloupce, ale pokud někdy spustíte doctrine:schema:update
přidá tento sloupec za vás. Bohužel Doctrine ve skutečnosti neumožňuje virtuální vlastnosti, takže dalším řešením by bylo napsat si vlastní hydratátor nebo se přihlásit k odběru loadClassMetadata
událost a ručně přidejte mapování po načtení vaší konkrétní entity (nebo entit).
Všimněte si, že pokud uděláte něco jako COUNT(r.id) AS reviewsCount
pak již nemůžete používat COUNT(id)
ve vašem addFieldResult()
a musí místo toho použít alias reviewsCount
pro tento druhý parametr.
Můžete také použít ResultSetMappingBuilder
jako začátek používání mapování sady výsledků.
Můj skutečný návrh je udělat to ručně, místo toho, abyste procházeli všemi těmi dalšími věcmi. V podstatě vytvořte normální dotaz, který vrátí vaši entitu i skalární výsledky do pole, poté nastavte skalární výsledek na odpovídající, nenamapované pole vaší entity a vraťte entitu.