我有一个VARCHAR(MAX)列,其中包含少量数据,我需要将其作为流传递给其他对象。我想避免将整个数据加载到内存中。听起来我可以使用SqlChars对象访问数据,而无需将其完全加载到内存中:
using (SqlCommand cmd = new SqlCommand("SELECT [Data] FROM [StreamingSample] WHERE [id] = @id", conn))
{
cmd.CommandTimeout = int.MaxValue;
cmd.Parameters.AddWithValue("id", iID);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
//Get index of column, so we don't assume the column order of the resultset
int iColumnIndex = reader.GetOrdinal("Data");
return reader.GetSqlChars(iColumnIndex);
}
}
}
然后我注意到SqlChars对象具有读取方法(microsoft docs:
public long Read (long offset, char[] buffer, int offsetInBuffer, int count);
所以我认为我可以以某种方式创建一个流对象,该对象的read方法包装了SqlChars read方法并将字符编码为字节。
public class SqlCharsStreamAdaptor : Stream
{
private readonly SqlChars input_m;
private Encoding enccoding_m;
public SqlCharsStream(Encoding encoding, SqlChars input)
: base()
{
input_m = input;
enccoding_m = encoding;
}
...
public override int Read(byte[] buffer, int iBufferOffset, int iBytesToRead)
{
...
//read portion of characters we need from sql
(int)this.input_m.Read(this.iCharPosition_m, this.chBuffer_m, 0, iCharsToReadFromSql);
//convert chars to bytes and return in buffer
...
}
}
有人做过这样的事情吗?有更容易的方法吗?分贝中的值可能是100的mb甚至是几gb。我们要避免占用大量内存,并且需要将数据传递给接受流的函数,因此我们希望避免将所有内容加载到内存流中。
答案 0 :(得分:0)
您将需要使用:SqlDataReader中的reader.GetStream。
示例:
using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess)) {
if (await reader.ReadAsync()) {
if (!(await reader.IsDBNullAsync(0))) {
using (Stream data = reader.GetStream(0)) {
// consume your steam
}
}
}
中找到更多信息