Потоковая передача 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-объектов.