sql >> Base de Datos >  >> RDS >> Mysql

¿Es posible usar el resultado de una función SQL como un campo en Doctrine?

Puede mapear un resultado de una sola columna a un campo de entidad - mira consultas nativas y Mapeo de conjunto de resultados lograr esto. Como un ejemplo simple:

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

Luego, en su entidad Producto, tendría un $reviewsCount y el conteo se asignaría a eso. Ten en cuenta que esto solo funcionará si tienes una columna definida en los metadatos de Doctrine, así:

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

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

Esto es lo que sugiere Campos agregados Documentación de la doctrina. El problema aquí es que esencialmente estás haciendo que Doctrine piense que tienes otra columna en tu base de datos llamada reviews_count , que es lo que no quieres. Entonces, esto seguirá funcionando sin agregar físicamente esa columna, pero si alguna vez ejecuta un doctrine:schema:update va a agregar esa columna por usted. Desafortunadamente, Doctrine realmente no permite propiedades virtuales, por lo que otra solución sería escribir su propio hidratante personalizado, o tal vez suscribirse a loadClassMetadata evento y agregue manualmente el mapeo usted mismo después de que se cargue su entidad (o entidades) en particular.

Tenga en cuenta que si hace algo como COUNT(r.id) AS reviewsCount entonces ya no puedes usar COUNT(id) en su addFieldResult() función, y en su lugar debe utilizar el alias reviewsCount para ese segundo parámetro.

También puedes usar el ResultSetMappingBuilder como un comienzo para usar el mapeo del conjunto de resultados.

Mi sugerencia real es hacer esto manualmente en lugar de pasar por todas esas cosas adicionales. Esencialmente, cree una consulta normal que devuelva tanto su entidad como los resultados escalares en una matriz, luego establezca el resultado escalar en un campo correspondiente no asignado en su entidad y devuelva la entidad.