Как вернуть пустую коллекцию Doctrine_Collection?

У меня есть метод, который возвращает Doctrine_Collection с предложением whereIn():

public function getByValues($values)
{
  if (!is_array($values))
    throw new sfException('Wrong parameter type. Excepted array.');

  return Doctrine_Query::create()
    ->from('Anomaly a')
    ->whereIn('a.value', $values);
}

Однако, когда $values является пустым массивом, этот метод возвращает все строки, которые есть в AnomalyTable. Это не является неожиданным поведением, как описано в документации Doctrine и написано здесь: ">Где Doctrine с Doctrine_Query

Однако я хотел бы вернуть пустой Doctrine_Collection вместо результата моего запроса, когда $values является пустым массивом.

Любые идеи о том, как я могу это сделать?

Спасибо =)

Редактировать:

Добавление невозможного предложения, такого как ->where('1=0'), помогло бы, но это ненужный запрос к серверу БД. У кого-нибудь есть идея получше?


person Clement Herreman    schedule 05.04.2011    source источник
comment
Почему вы все еще хотите запрашивать БД, если вы уже знаете, что ничего не получите? Просто проверьте $values, и если он пуст - вообще не запрашивайте.   -  person artshpakov    schedule 05.04.2011
comment
Я не хочу запрашивать, если $values пуст, просто возвращаю пустой Doctrine_Collection   -  person Clement Herreman    schedule 05.04.2011


Ответы (5)


А как насчет (вам также нужен метод execute для получения результата запроса! При этом тип возвращаемого значения будет одинаковым каждый раз):

public function getByValues($values)
{
  if (!is_array($values))
    throw new sfException('Wrong parameter type. Excepted array.');

  if (empty($values)) {
    return new Doctrine_Collection('Anomaly');
  }

  return Doctrine_Query::create()
    ->from('Anomaly a')
    ->whereIn('a.value', $values)
    ->execute()
  ;
}
person jeremyFreeAgent    schedule 05.04.2011

По значению, я полагаю, вы имеете в виду $values, верно? просто добавьте что-нибудь, чтобы проверить, пусты ли значения, а затем вручную укажите пустую коллекцию.

if(empty($values)) 
   return Doctine_Query::create()->from('Anomaly a')->where('1=0');
person Jason    schedule 05.04.2011
comment
Может быть, потому что таким образом вы загружаете свой сервер БД запросами, которые ничего не делают? - person artshpakov; 05.04.2011
comment
& @nicola: я думаю, что это умный способ, но, как предполагает Wallgate, это был бы ненужный запрос к серверу БД. - person Clement Herreman; 05.04.2011

Я думаю, что это невозможно сделать. Doctrine_Collection — это больше, чем набор/массив объектов. Он также имеет средства для удаления и добавления объектов и сохранения этого состояния.

Возможно, именно поэтому многие нативные функции Doctrine возвращают FALSE, когда результаты не найдены. (Например, функции NestedSet).

Итак, для вас, вероятно, лучше также вернуть FALSE. или, может быть, пустой массив. Оба массива как Doctrine_Collection можно использовать в цикле foreach и функции count. Если вы хотите использовать функции delete и add, вы можете просто вызвать конструктор.

person Grad van Horck    schedule 05.04.2011
comment
Ty за точность роли Doctrine_Collection. - person Clement Herreman; 05.04.2011

Я лично использую следующий трюк:

public function getByValues($values)
{
  if (!is_array($values))
    throw new sfException('Wrong parameter type. Excepted array.');

  $values = empty($values) ? array(-1) : $values;

  return Doctrine_Query::create()
    ->from('Anomaly a')
    ->whereIn('a.value', $values);
}

Отлично работает, даже если несколько хакерский.

person NiKo    schedule 05.04.2011
comment
Работает хорошо, пока -1 является невозможным значением. Я думаю, я буду придерживаться этого. - person Clement Herreman; 05.04.2011
comment
Я поставил -1, потому что предложения WHERE IN часто используются в первичных ключах, но вы можете установить ChuckNorr1z как невозможное значение, если вы этого не боитесь;) - person NiKo; 05.04.2011
comment
Таким образом, у вас все еще будет (ненужный) путь туда и обратно к базе данных. - person Grad van Horck; 05.04.2011

person    schedule
comment
$values.length? values ​​- это массив, а не объект. Также вам не хватает точки с запятой, мистер Мун :) - person Jason; 05.04.2011