Можете да картографирате резултат от една колона към поле на обект - вижте родни заявки и ResultSetMapping за да постигнем това. Като прост пример:
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();
След това във вашия обект Продукт ще имате $reviewsCount
поле и броят ще бъде съпоставен с това. Имайте предвид, че това ще работи само ако имате колона, дефинирана в метаданните на Doctrine, така:
/**
* @ORM\Column(type="integer")
*/
private $reviewsCount;
public function getReviewsCount()
{
return $this->reviewsCount;
}
Това се предлага от Обобщени полета
Документация на доктрината. Проблемът тук е, че по същество карате Doctrine да мисли, че имате друга колона във вашата база данни, наречена reviews_count
, което не искате. Така че това все още ще работи без физическо добавяне на тази колона, но ако някога стартирате doctrine:schema:update
ще добави тази колона за вас. За съжаление Doctrine всъщност не позволява виртуални свойства, така че друго решение би било да напишете свой собствен персонализиран хидрататор или може би да се абонирате за loadClassMetadata
събитие и ръчно добавете картографирането сами след зареждане на вашия конкретен обект (или обекти).
Имайте предвид, че ако направите нещо като COUNT(r.id) AS reviewsCount
тогава вече не можете да използвате COUNT(id)
във вашия addFieldResult()
функция и вместо това трябва да използва псевдонима reviewsCount
за този втори параметър.
Можете също да използвате ResultSetMappingBuilder
като начало за използване на съпоставянето на набора от резултати.
Истинското ми предложение е да направите това ръчно, вместо да преминавате през всички тези допълнителни неща. По същество създайте нормална заявка, която връща както вашия обект, така и скаларни резултати в масив, след което задайте скаларния резултат на съответното несъпоставено поле на вашия обект и върнете обекта.