执行 DQL 查询时,例如:
SELECT u AS user, t AS transaction
FROM ModelUser u
JOIN ModelTransaction t WITH t.user = u
您将获得交替的结果行,例如:
-
['user' => ModelUser(1)]
-
['transaction' => ModelTransaction(1)]
-
['transaction' => ModelTransaction(2)]
-
['user' => ModelUser(2)]
-
['transaction' => ModelTransaction(3)]
-
['transaction' => ModelTransaction(4)]
-
['transaction' => ModelTransaction(5)]
是否可以以SQL方式获得结果,例如:
-
['user' => ModelUser(1), 'transaction' => ModelTransaction(1)]
-
['user' => ModelUser(1), 'transaction' => ModelTransaction(2)]
-
['user' => ModelUser(2), 'transaction' => ModelTransaction(3)]
-
['user' => ModelUser(2), 'transaction' => ModelTransaction(4)]
-
['user' => ModelUser(2), 'transaction' => ModelTransaction(5)]
它比交替对象更容易处理。
不幸的是,目前没有简单的方法来实现这一目标。但是,有一种方法可以得到这个结果。
创建一个名为 UserTransactionDTO 的类并接受 2 个构造函数参数:User 和 Transaction。
现在重写 DQL 查询,如下所示:
SELECT NEW UserTransactionDTO(user, transaction)
FROM ModelUser u
JOIN ModelTransaction t WITH t.user = u
这应该为您提供与所需行为匹配的结果(UserTransactionDTO 对象列表),允许您在单个记录上访问用户和事务。
我现在的做法是:
$query = $em->createQuery('
SELECT u, t
FROM ModelUser u
JOIN ModelTransaction t WITH t.user = u
');
$rows = $query->getResult();
$rowCount = count($rows);
$result = [];
for ($i = 0; $i < $rowCount; $i += 2) {
/** @var ModelUser $user */
$user = $rows[$i];
/** @var ModelTransaction $transaction */
$transaction = $rows[$i + 1];
$result[] = new UserTransactionDTO($user, $transaction);
}
return $result;
哪个足够干净。
请注意,这个例子很糟糕,因为你只能返回事务并从那里获取用户;但我经常遇到单个对象不能保存所有信息的用例。