问题描述
我有一个 SqlDataReader,需要使用 SqlDataReader.GetBytes() 方法从中读取一个 varbinary(max) 列.此方法填充一个字节数组,因此需要知道要读取的数据长度.
I have a SqlDataReader and need to read a varbinary(max) column from it using the SqlDataReader.GetBytes() method. This method populates a byte array and therefore needs to know what length of data to read.
这就是我感到困惑的地方.显然我想读取从数据库返回的所有数据在这一行/列中,那么我应该传递什么长度"参数?
This is where I get confused.. Clearly I want to read all the data that has been returned from the database in this row/column so what 'length' parameter should I pass?
据我所知,SqlDataReader 没有提供任何方法来发现可用数据的长度,因此这种方法对我来说似乎相当尴尬.
As far as I can see, the SqlDataReader doesn't provide any methods to discover what length of data is available, therefore this method seems fairly awkward to me.
我很想在这里传递 int.MaxValue 并忘记这个问题,但我对此并不满意.
I'm tempted to just pass int.MaxValue here and forget about the issue but something about this doesn't sit right with me.
我知道我可以改为调用
byte[] value = (byte[])dataReader["columnName"];
.. 这似乎完全解决了内部的长度问题.但是,我正在使用围绕 SqlDataReader.GetXXXX() 方法构建的一组复杂的代码生成模板.所以我对使用 GetBytes 很感兴趣,需要了解它的正确用法.
.. and this seems to completely take care of the length issue internally. However I am working with a set of complicated code generation templates that have been built around the SqlDataReader.GetXXXX() methods. So I am tied into using GetBytes and need to understand its proper usage.
推荐答案
在处理varbinary(max)
时,有两种情况:
When dealing with varbinary(max)
, there are two scenarios:
- 数据长度适中
- 数据的长度很大
GetBytes()
适用于 second 场景,当您使用 CommandBehaviour.SequentialAccess
来确保您在 流式传输 数据,而不是 缓冲 它.特别是,在这种用法中,您通常会(例如)在流中、在循环中写入.例如:
GetBytes()
is intended for the second scenario, when you are using CommandBehaviour.SequentialAccess
to ensure that you are streaming the data, not buffering it. In particular, in this usage you would usually be writing (for example) in a stream, in a loop. For example:
// moderately sized buffer; 8040 is a SQL Server page, note
byte[] buffer = new byte[8040];
long offset = 0;
int read;
while((read = reader.GetBytes(col, offset, buffer, 0, buffer.Length)) > 0) {
offset += read;
destination.Write(buffer, 0, read); // push downstream
}
但是!如果您使用的是中等大小的数据,那么您的原始代码:
However! If you are using moderately sized data, then your original code:
byte[] data = (byte[])reader[col];
很好!!.这种方法没有任何问题,实际上 Get*
API 在某些情况下会损坏 - GetChar()
就是一个值得注意的例子(提示:它不起作用).
is fine!!. There is nothing wrong with this approach, and in fact the Get*
API is broken in a few cases - GetChar()
being a notable example (hint: it doesn't work).
您有使用 Get*
的现有代码没关系 - 在这种情况下,强制转换方法非常合适.
It doesn't matter that you have existing code that uses Get*
- in this case, the cast approach is perfectly appropriate.
这篇关于我应该将什么“长度"参数传递给 SqlDataReader.GetBytes()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!