Может быть, что-то простое, но мой конструктор запросов не возвращает то, что я хочу. Я бы что-то вроде … где … И (…. ИЛИ ….)
Я пытаюсь прочитать документацию по доктрине, но я не владею английским языком, поэтому я не совсем понимаю документацию по доктрине (возможно, есть перевод на французский?).
<?php
// $qb instanceof QueryBuilder
$qb->select(array('u')) // string 'u' is converted to array internally
->from('User', 'u')
->where($qb->expr()->orX(
$qb->expr()->eq('u.id', '?1'),
$qb->expr()->like('u.nickname', '?2')
))
->orderBy('u.surname', 'ASC'));
Вот мой тестовый код MySQL, который работает
select count(distinct(u.username)) from fos_user u join users_accounts ua ON u.id=ua.user_id join account acc ON acc.id = ua.account_id where u.id=48 and (acc.id=2 OR acc.id=5)
Вот построитель запросов:
Я пользуюсь услугой, потому что мне приходилось использовать эту функцию более одного раза.
/**
* Check if User exists in one of the connected user (Admin or SupAdmin) accounts
* argument : userID
*
*/
public function userExists($userID)
{
// Return accounts (array)
$accounts = $this->accountManager->listAccountsByConnectedUser();
$repository = $this->em->getRepository('CMiNewsBundle:User');
$qb = $repository->createQueryBuilder('u');
$query = $qb
->select('count(u)')
->join ('u.accounts', 'acc')
->where('u.id = :userID')
->andwhere('acc.id = :accountID')
->setParameters(array(
'userID' => $userID,
'accountID' => $accounts[0]->getId(),
));
if (count($accounts) > 1) {$accountMax = count($accounts);
for($acc=1; $acc<$accountMax; $acc++)
{
$query->orWhere('acc.id = :accountID_'.$acc.'')->setParameter('accountID_'.$acc.'', $accounts[$acc]->getId());
}
};
$query = $query->getQuery();
$result = $query->getResult();
return $result;
}
Спасибо за ваши советы
Вы можете переписать ваш запрос как IN()
в MySQL, как показано ниже
SELECT
COUNT(DISTINCT (u.username))
FROM
fos_user u
JOIN users_accounts ua
ON u.id = ua.user_id
JOIN account acc
ON acc.id = ua.account_id
WHERE u.id = 48
AND acc.id IN(2,5) /* this is equivalent to acc.id = 2 or acc.id = 5 */
Текущий запрос для доктрины, которую вы используете, игнорирует ваш запрос и условие, как если бы у вас было 2 идентификатора аккаунта, запрос будет
WHERE u.id = 48 AND acc.id = 2 OR acc.id = 5
Так что это даст записи для acc.id = 5
а также u.id
может быть любой другой идентификатор
Для запроса доктрины вы можете переписать свой код, как показано ниже. Вы должны создать массив идентификаторов учетных записей и передать этот массив в свой IN()
пункт
public function userExists($userID)
{
// Return accounts (array)
$accounts = $this->accountManager->listAccountsByConnectedUser();
$repository = $this->em->getRepository('CMiNewsBundle:User');
$qb = $repository->createQueryBuilder('u');
$accounts=array();
$accounts[]=$accounts[0]->getId();
if (count($accounts) > 1) {
$accountMax = count($accounts);
for ($acc = 1; $acc < $accountMax; $acc++) {
$accounts[]=$accounts[$acc]->getId();
}
}
$query = $qb
->select('count(u) as your_count')
->join('u.accounts', 'acc')
->where('u.id = :userID')
->andwhere('acc.id IN(:accountID)')
->setParameters(array(
'userID' => $userID,
'accountID' => $accounts,
));
$query = $query->getQuery();
$result = $query->getResult();
return $result;
}
Других решений пока нет …