sql >> Database >  >> RDS >> Mysql

Is het mogelijk om het resultaat van een SQL-functie als een veld in Doctrine te gebruiken?

U kunt een resultaat uit één kolom naar een entiteitsveld - kijk naar native queries en ResultSetMapping om dit te behalen. Als een eenvoudig voorbeeld:

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();

Dan zou u in uw productentiteit een $reviewsCount . hebben veld en de telling zou daaraan worden toegewezen. Merk op dat dit alleen werkt als je een kolom hebt gedefinieerd in de Doctrine-metadata, zoals:

/**
 * @ORM\Column(type="integer")
 */
private $reviewsCount;

public function getReviewsCount()
{
    return $this->reviewsCount;
}

Dit is wat wordt gesuggereerd door de Geaggregeerde velden Doctrine documentatie. Het probleem hier is dat je Doctrine in wezen laat denken dat je een andere kolom in je database hebt met de naam reviews_count , dat is wat je niet wilt. Dit werkt dus nog steeds zonder die kolom fysiek toe te voegen, maar als u ooit een doctrine:schema:update uitvoert het gaat die kolom voor je toevoegen. Helaas staat Doctrine niet echt virtuele eigenschappen toe, dus een andere oplossing zou zijn om je eigen aangepaste hydrator te schrijven, of je misschien te abonneren op de loadClassMetadata gebeurtenis en voeg de toewijzing zelf handmatig toe nadat uw specifieke entiteit (of entiteiten) is geladen.

Houd er rekening mee dat als u iets doet als COUNT(r.id) AS reviewsCount dan kun je COUNT(id) niet meer gebruiken in uw addFieldResult() functie, en moet in plaats daarvan de alias reviewsCount . gebruiken voor die tweede parameter.

U kunt ook de gebruiken ResultSetMappingBuilder als een begin voor het gebruik van de mapping van de resultatenset.

Mijn eigenlijke suggestie is om dit handmatig te doen in plaats van al die extra dingen door te nemen. Maak in wezen een normale query die zowel uw entiteits- als scalaire resultaten in een array retourneert, stel vervolgens het scalaire resultaat in op een overeenkomstig, niet-toegewezen veld op uw entiteit en retourneer de entiteit.



  1. hoe ziet een B-tree index op meer dan 1 kolom eruit?

  2. De resultaten van een query e-mailen in SQL Server (T-SQL)

  3. Welke situaties zorgen ervoor dat Oracle-pakketten ongeldig worden?

  4. MySQL TIMESTAMP naar QDateTime met milliseconden