2016-05-31 2 views
2

При выполнении запроса DQL, такие как:Получение Doctrine DQL приводит к SQL путь

SELECT u AS user, t AS transaction 
FROM Model\User u 
JOIN Model\Transaction t WITH t.user = u 

Вы получаете чередующихся рядов результатов, таких как:

  • ['user' => Model\User(1)]
  • ['transaction' => Model\Transaction(1)]
  • ['transaction' => Model\Transaction(2)]
  • ['user' => Model\User(2)]
  • ['transaction' => Model\Transaction(3)]
  • ['transaction' => Model\Transaction(4)]
  • ['transaction' => Model\Transaction(5)]

Можно ли получить результат в SQL так, как:

  • ['user' => Model\User(1), 'transaction' => Model\Transaction(1)]
  • ['user' => Model\User(1), 'transaction' => Model\Transaction(2)]
  • ['user' => Model\User(2), 'transaction' => Model\Transaction(3)]
  • ['user' => Model\User(2), 'transaction' => Model\Transaction(4)]
  • ['user' => Model\User(2), 'transaction' => Model\Transaction(5)]

Было бы гораздо легче иметь дело с чем чередующимися объектами.

ответ

0

Как мне это сделать сейчас:

$query = $em->createQuery(' 
    SELECT u, t 
    FROM Model\User u 
    JOIN Model\Transaction t WITH t.user = u 
'); 

$rows = $query->getResult(); 
$rowCount = count($rows); 

$result = []; 

for ($i = 0; $i < $rowCount; $i += 2) { 
    /** @var Model\User $user */ 
    $user = $rows[$i]; 

    /** @var Model\Transaction $transaction */ 
    $transaction = $rows[$i + 1]; 

    $result[] = new UserTransactionDTO($user, $transaction); 
} 

return $result; 

Который достаточно чистый.

Обратите внимание, что этот пример является плохим, поскольку вы можете только возвращать транзакции и получать от Пользователя; но я регулярно встречаю случаи использования, когда один объект не содержит всю информацию.

0

К сожалению, нет тока легко Способ достижения этого. Тем не менее, есть способ получить этот результат.

Создайте класс с именем UserTransactionDTO и примите 2 аргумента конструктора: Пользователь и транзакция.

Теперь переписать DQL запрос так:

SELECT NEW UserTransactionDTO(user, transaction) 
    FROM Model\User u 
    JOIN Model\Transaction t WITH t.user = u 

Это должно дать вам результат, который соответствует вашему желаемому поведению (список объектов UserTransactionDTO), что позволяет получить доступ как пользователя и сделку по одной записи ,

+0

Спасибо, я попробовал это, но мой конструктор получает идентификаторы объектов, а не объекты, в качестве аргументов! Может быть, ключевое слово NEW есть только для скаляров? – Benjamin

+1

Из http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#new-operator-syntax "Обратите внимание, что вы можете передавать только скалярные выражения к конструктору ». – eggmatters

+0

Одна вещь, о которой я не упоминал, это то, что я работаю над проектом Doctrine. Поддержка этого - вопрос открытия проблемы. Однако главный вопрос должен быть рассмотрен на Доктрине 3, так как я сейчас работаю над этим. –

Смежные вопросы