Вернуть в качестве ключа выборки значение одного из столбцов — довольно частая задача. Достичь результата можно несколькими способами.
INDEX BY
createQuery()
Если Вы создаете запрос используя createQuery
, то достаточно добавить к конструкции FROM
конструкцию INDEX BY column_name
.
namespace DemoBundle\Repository;
use Doctrine\ORM\EntityRepository;
class SettingsRepository extends EntityRepository
{
public function getSettingsIndexedByName()
{
$query = $this->createQuery('SELECT s FROM DemoBundle:Settings s INDEX BY s.name');
return $query->getResult();
}
}
createQueryBuilder()
Но Вы наверняка используете QueryBuilder для создания запросов, он также позволяет использовать indexBy. Метод createQueryBuilder
принимает два параметра: alias и indexBy.
namespace DemoBundle\Repository;
use Doctrine\ORM\EntityRepository;
class SettingsRepository extends EntityRepository
{
public function getSettingsIndexedByName()
{
$qb = $this->createQueryBuilder('s', 's.name')
->select('s');
$query = $qb->getQuery();
return $query->getResult();
}
}
Однако в предыдущих версиях Doctrine (например 2.4.7) метод createQueryBuilder выглядит следующим образом.
public function createQueryBuilder($alias)
{
return $this->_em->createQueryBuilder()
->select($alias)
->from($this->_entityName, $alias);
}
Как видите, нет параметра indexBy. Решить эту проблему можно расширив класс Doctrine\ORM\EntityRepository
.
namespace DemoBundle\Repository;
use Doctrine\ORM\EntityRepository as DoctrineEntityRepository;
class EntityRepository extends DoctrineEntityRepository
{
public function createQueryBuilder($alias, $indexBy = null)
{
return $this->_em->createQueryBuilder()
->select($alias)
->from($this->_entityName, $alias, $indexBy);
}
}
Теперь Вам нужно только унаследовать от него свои классы-репозитории и воспользоваться переопределенным методом createQueryBuilder()
Hydrators
Также изменить вид результирующей выборки можно при помощи гидраторов. Но это уже тема для отдельной статьи.