Потоковая передача VARBINARY данных из SQL Server в С#

Я пытаюсь использовать данные изображения, хранящиеся в поле VARBINARY (MAX) в базе данных, используя ASP.Net. Прямо сейчас код заполняет таблицу данных, а затем вытаскивает массив байтов из DataRow и подталкивает массив байтов в ответ. Мне интересно, есть ли способ более или менее потока данных из SQL Server в ответ без необходимости маршалировать эти огромные массивы байтов (поскольку изображения большие, они вызывают OutOfMemoryExceptions). Есть ли для этого класс/механизм?

Текущий код выглядит примерно так:

DataTable table = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(commandText, connectionString);
adapter.Fill(table);
DataRow row = table.Rows[0];
byte[] imageData = row[0] as byte[];
if(imageData != null)
{
  Response.Clear();
  Response.BinaryWrite(imageData);
  Response.End();
}

Спасибо заранее - любая помощь приветствуется.

Ответ 1

См. Загрузка и загрузка изображений с SQL Server для статьи, посвященной этой теме, включая эффективную семантику потоковой передачи. Вы должны использовать SqlDataReader, открытый с помощью CommandBehavior.SequentialAccess

SequentialAccess Предоставляет способ DataReader для обработки строк, которые содержат столбцы с большими двоичными значения. Вместо загрузки всего строка, SequentialAccess позволяет DataReader для загрузки данных в виде потока. Затем вы можете использовать GetBytes или Метод GetChars для указания байта местоположение, чтобы начать операцию чтения, и ограниченный размер буфера для данных возвращается.

Связанная статья содержит полный код для создания потока, поддерживаемого SqlDataReader, вы можете просто Stream.CopyTo (HttpResponse.OutputStream), или используйте побитую копию byte [], если у вас еще нет .Net 4.0.

В следующей статье описывается как использовать столбец FILESTREAM для эффективной потоковой передачи больших данных VARBINARY в базе данных и из нее.

Ответ 2

Ответ @Remus выше устарел, так как .NET 4.5 представила первоклассную потоковую передачу SqlClient. Больше нет необходимости обращаться к методам SqlDataReader GetBytes(), чтобы получить поток из SQL-запроса.

Теперь вы просто вызываете SqlDataReader.GetStream(int), чтобы получить поток через столбец BLOB-объектов.