sql >> Databasteknik >  >> RDS >> Mysql

Är det möjligt att använda resultatet av en SQL-funktion som ett fält i Doctrine?

Du kan mappa en resultat från en kolumn till ett enhetsfält - titta på native queries och ResultSetMapping för att uppnå detta. Som ett enkelt exempel:

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

Sedan i din produktenhet skulle du ha en $reviewsCount fältet och antalet skulle mappas till det. Observera att detta bara fungerar om du har en kolumn definierad i Doktrinens metadata, som så:

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

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

Detta är vad som föreslås av Aggregerade fält Doktrindokumentation. Problemet här är att du i grunden får Doctrine att tro att du har en annan kolumn i din databas som heter reviews_count , vilket är vad du inte vill ha. Så detta kommer fortfarande att fungera utan att fysiskt lägga till den kolumnen, men om du någonsin kör en doctrine:schema:update det kommer att lägga till den kolumnen åt dig. Tyvärr tillåter Doctrine inte riktigt virtuella egenskaper, så en annan lösning skulle vara att skriva din egen anpassade hydrator, eller kanske prenumerera på loadClassMetadata händelse och manuellt lägg till mappningen själv efter att just din entitet (eller entiteter) har laddats.

Observera att om du gör något som COUNT(r.id) AS reviewsCount då kan du inte längre använda COUNT(id) i din addFieldResult() funktion och måste istället använda aliaset reviewsCount för den andra parametern.

Du kan också använda ResultSetMappingBuilder som en början till att använda resultatuppsättningsmappingen.

Mitt faktiska förslag är att göra detta manuellt istället för att gå igenom allt det där extra. Skapa i huvudsak en normal fråga som returnerar både din entitet och dina skalära resultat till en array, ställ sedan in det skalära resultatet till ett motsvarande, omappat fält på din entitet och returnera entiteten.



  1. Jag kan inte ladda JDBC-drivrutinen för MySQL

  2. Hur RADIANS() fungerar i MariaDB

  3. Uppdaterar Salesforce från Oracle®

  4. PSQL kommandoradsargument i DO-skript