Измените ключ массива getResult для значения первичного ключа

Можно ли изменить значения ключа массива для getResult() в Doctrine2?

Пример:

$qb->select('t.id, t.name')->from('Table', 't');

Когда я печатаю это, я получаю, чего я не хотел:

print_r($qb->getQuery()->getResult());

//Print result: Array ( [0] => Array ( [id] => 20 [name] => Name1 ) [1] => Array ( [id] => 21 [percentagem] => Name2 ) )

Я хочу:

Array ( [20] => Array ( [id] => 20 [name] => Name1 ) [21] => Array ( [id] => 21 [percentagem] => Name2 ) )

Предложения, подсказки будут оценены.

Ответ 1

Я на самом деле очень рад, насколько это круто:

$query = $this->getEntityManager()->createQuery('
            SELECT user FROM UserBundle:User user
            INDEX BY user.id
            WHERE user.id = 1
            '
        );

Конструкция INDEX BY не является чем-то, что непосредственно переводит на SQL, но это влияет на гидратацию объектов и массивов. После каждого предложения FROM и JOIN вы указываете, по какому полю этот класс должен быть проиндексирован в результате. По умолчанию результат увеличивается с помощью числовых ключей, начинающихся с 0. Однако с помощью INDEX BY вы можете указать любой другой столбец, который будет ключом к вашему результату, однако это действительно имеет смысл только с первичными или уникальными полями.

Источник: Doctrine ORM 2 Документация Использование INDEX BY

  • Пожалуйста, используйте ИНДЕКС BY до ГДЕ

Ответ 2

Однако, для полноты, вы можете сделать то же самое с построителем запросов, как показано ниже:

$queryBuilder = $this->getEntityManager()->createQueryBuilder();

$queryBuilder
    ->select('user')
    ->from('UserBundle:User', 'user', 'user.id')
    ->where('user.id = :userId')
    ->setParameter('userId', $userId)
;

var_dump(
    $queryBuilder->getQuery()->getArrayResult()
);

Как вы можете видеть, индекс по параметру доступен в качестве третьего параметра построителя запросов from метода:

/**
 * Creates and adds a query root corresponding to the entity identified by the given alias,
 * forming a cartesian product with any existing query roots.
 *
 * <code>
 *     $qb = $em->createQueryBuilder()
 *         ->select('u')
 *         ->from('User', 'u')
 * </code>
 *
 * @param string $from    The class name.
 * @param string $alias   The alias of the class.
 * @param string $indexBy The index for the from.
 *
 * @return QueryBuilder This QueryBuilder instance.
 */
public function from($from, $alias, $indexBy = null)
{
    return $this->add('from', new Expr\From($from, $alias, $indexBy), true);
}

Ответ 3

Просто используйте 3-й параметр ->from(entity, alias, indexBy)

Итак, вместо этого

$qb->select('t.id, t.name')->from('Table', 't');

использование

$qb->select('t.id, t.name')->from('Table', 't', 'Table.id');

PS: @Франческо-Касула написал хороший ответ с небольшими подробностями, хорошо.