Как конвертировать IDataReader в поток в C#

В моей службе WCF я получаю данные с сервера SQL, используя Command.ExecuteReader() метод. Размер данных очень большой (около 1+ ГБ) и передает эти данные клиенту через привязку netTcp.

Я планирую реализовать потоковый режим вместо буферизованного режима в WCF. Может кто-нибудь указать мне на любую статью или документ, чтобы сделать то же самое.

Проще говоря, моя цель - преобразовать IDataReader в потоковый объект, который будет передаваться на клиентскую и клиентскую стороны, хотите преобразовать этот поток обратно в набор данных / datatable или все, что может быть связано с Grid.

Я не могу преобразовать IdataReader в IEnumerable, так как данные поступают через SP, и ни один из столбцов в выходном наборе не меняется (я не хочу добавлять ограничение кода в коде).

В конечном счете, окончательный обмен данными будет осуществляться по набору данных от службы WCF к клиентскому приложению. Если какое-либо решение, такое как преобразование набора данных в поток, отправка его клиенту и клиенту, преобразование потока обратно в набор данных также решит мою проблему.

2 ответа

Решение

Вы не должны пытаться преобразовать IDataReader в поток, но пусть ваш метод доступа к данным возвращает IEnumerable типа, представляющего одну строку результата запроса, например:

public IEnumerable<Order> GetOrders()
{
   IDbCommand cmd = ...  <<build your command here>> ...
   using(var rdr = cmd.ExecuteDataReader())
   {
      while(rdr.Read())
      {
          Order order = new Order {Id=rdr.GetDecimal(1), Name=rdr.GetString(2)};
          yield return order;
      }
   }
}

Затем вы можете сериализовать результат этого метода в поток (как показано, например, @Mohamed). Таким образом, вы можете отправить список объектов клиенту без необходимости загрузки полного набора результатов в память. И вы по-прежнему уверены, что устройство чтения данных удаляется, когда читатель достиг конца результата.

Вы можете преобразовать что угодно в поток, как это:

var stream = new MemoryStream(Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(datareader)));

но это не лучшая практика. Вы должны создать массив объектов с вашим устройством чтения данных, а затем вернуть его.

Другие вопросы по тегам