Если необходимо прочитать данные от SqlServer в потоковом режиме, для этого есть некоторые возможности. Такие, как с помощью SqlDataReader
с CommandBehavior.SequentialAccess
, и, в частности, когда необходимо получить доступ двоичные данные столбца существует GetStream(int)
метод, что:Поставка потока в качестве источника данных для двоичного столбца при использовании SqlBulkCopy
var cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandText = @"select 0xas Data";
using (var dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
dr.Read();
var stream = dr.GetStream(0);
// access stream
}
Но что потоковой передачи данных в противоположном направлении, когда нужно датафид к SqlServer с использованием SqlBulkCopy
, и особенно если поток должен быть предоставлен в качестве источника данных для двоичного столбца?
Я попытался следующие
var cmd2 = new SqlCommand();
cmd2.Connection = connection;
cmd2.CommandText = @"create table #Test (ID int, Data varbinary(max))";
cmd2.ExecuteNonQuery();
using (SqlBulkCopy sbc = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null))
{
sbc.DestinationTableName = "#Test";
sbc.EnableStreaming = true;
sbc.ColumnMappings.Add(0, "ID");
sbc.ColumnMappings.Add(1, "Data");
sbc.WriteToServer(new TestDataReader());
}
Где TestDataReader
реализует IDataReader
следующим образом:
class TestDataReader : IDataReader
{
public int FieldCount { get { return 2; } }
int rowCount = 1;
public bool Read() { return (rowCount++) < 3; }
public bool IsDBNull(int i) { return false; }
public object GetValue(int i)
{
switch (i)
{
case 0: return rowCount;
case 1: return new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89 };
default: throw new Exception();
}
}
//the rest members of IDataReader
}
, и она работала, как ожидалось.
Однако изменение
case 1: return new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89 };
к
case 1: return new MemoryStream(new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89 });
вызвало исключение System.InvalidOperationException
с сообщением
Данное значение типа MemoryStream из источника данных, не может быть преобразован в тип VARBINARY указанного целевого столбца.
Есть ли способ, чтобы поставить Stream
от IDataReader
(или, возможно, DbDataReader
), чтобы SqlBulkCopy
в качестве источника данных для двоичного столбца, без копирования всех данных в памяти (массив байт) в первую очередь?
См сайт: https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy (v = vs.110) .aspx – jdweng
Вам интересно, как это сделать с помощью пользовательского IDataReader, или на самом деле вы будете использовать какой-то существующий считыватель данных (например, SqlDataReader)? – Evk
@Evk с пользовательским 'IDataReader' или' DbDataReader' (я использую собственную реализацию, которая передает данные из двоичных/xml-файлов, однако достаточно фиктивной реализации, как в моем вопросе). –