2015-03-09 1 views
3

У меня есть запрос на базу данных (Cassandra), который возвращает IEnumerable. Попытка выяснить, почему это не возвращает никаких данных (когда я знаю, что есть данные в базе данных), я нашел любопытную проблему.Доступ к IEnumerable очищает содержимое

Запрос действительно возвращает данные, 25 записей. Я проверял это с помощью Data.Count(); Но позже в коде он был пуст. Я понял, что метод графа необъяснимо очищает данные.

После быстрого расследования: Любое чтение этих данных полностью очищает его. Даже при отладке, если я загружу «представление результатов», чтобы получить список данных, сначала я вижу свои 25 записей, затем, если я щелкнул, а затем перезагрузите представление результатов: Emtpy.

У кого-нибудь когда-либо было подобное?

 String connectionString = "SELECT * FROM thedatabase WHERE thecondition"; 

     RowSet Data = ExecuteComand(connectionString); 

     if (Data == null) // interestingly, I can check for null without issue 
     { 
      OutputMessage("Output to " + exportFile + " failed"); 
      return; 
     } 
     int b = Data.Count(); // results in 25 
     int c = Data.Count(); // results in 0 
+0

Не знаком с Кассандрой и ее разъемом, поэтому не уверен, почему он это делает. Возможно, настройка производительности, так что запрос выполняется только один раз? Я не знаю, подходит ли вам это, но вы пытались материализовать IEnumerable? Это var data = Data.ToList() и работать с этим? – Juan

+0

@Juan Это сработало, спасибо большое. – Joe

ответ

4

Я не знаю Кассандру, но я предполагаю, что возвращаемый IEnumerable<T> выполняется лениво (отложенный). Потребив его (например, с foreach, ToList или Count), запрос выполняется, а ресурсы (например, соединение) расположены/закрыты.

Если это так, вы можете загрузить его в коллекцию в памяти, например:

var data = ExecuteComand("SELECT * FROM thedatabase WHERE thecondition").ToList(); 

Теперь вы можете использовать data.Count без «очистки» он.

3

Там нет никакой гарантии, что Enumerable могут быть перечислены дважды. Правильно построенный перечислимый должен хотя бы вызывать исключение, но плохой код всегда может произойти. Что вы можете сделать, это материализовать его в хорошо себя коллекции существует List<T>, например:

var data2 = Data.ToList(); 

int b = data2.Count; 
int c = data2.Count; 

Теперь вы даже имеете преимущество, что Count является O (1) вместо O (N) :-) (в List<T> значение а Count является «кэшированные»)

+0

Спасибо, это сработало отлично. Мне нужно будет помнить об этом с помощью Enumerable в будущем. благодаря – Joe

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

  • Нет связанных вопросов^_^