DataReader 的默认行为是在整个数据行可用时立即以行的形式加载传入数据 但是 对于二进制大对象 (BLOB) 则需要进行不同的处理 因为它们可能包含数十亿字节的数据 而单个行中无法包含如此多的数据 Command ExecuteReader 方法具有一个重载 它将采用 CommandBehavior 参数来修改 DataReader 的默认行为 您可以将 CommandBehavior SequentialAccess 传递到 ExecuteReader 方法来修改 DataReader 的默认行为 以便让 DataReader 按照顺序在接收到数据时立即将其加载 而不是加载数据行 这是加载 BLOB 或其他大数据结构的理想方案 在将 DataReader 设置为使用 SequentialAccess 时 务必要注意访问所返回字段的顺序 DataReader 的默认行为是在整个行可用时立即加载该行 这使您能够在读取下一行之前按任何顺序访问所返回的字段 但是 当使用 SequentialAccess 时 必须按顺序访问由 DataReader 返回的不同字段 例如 如果查询返回三个列 其中第三列是 BLOB 则必须在访问第三个字段中的 BLOB 数据之前返回第一个和第二个字段的值 如果在访问第一个或第二个字段之前访问第三个字段 则第一个和第二个字段值将不再可用 这是因为 SequentialAccess 已修改 DataReader 使其按顺序返回数据 当 DataReader 已经读取超过特定数据时 该数据将不可用 当访问 BLOB 字段中的数据时 请使用 DataReader 的 GetBytes 类型化访问器 该访问器将使用二进制数据填充 byte 数组 您可以指定要返回的特定数据缓冲区大小以及从返回的数据中读取的第一个字节的起始位置 GetBytes 将返回 long 值 它表示所返回的字节数 如果向 GetBytes 传递空的 byte 数组 所返回的长值将是 BLOB 中字节的总数 您可以选择将字节数组中的某索引指定为所读取数据的起始位置 以下示例从 Microsoft SQL Server 中的 pubs 示例数据库中返回发行者 ID 和徽标 发行者 ID (pub_id) 是字符字段 而徽标则是图形 即 BLOB 请注意 由于必须按顺序访问字段 所以将在访问徽标之前访问当前数据行的发行者 ID [Visual Basic]Dim pubsConn As SqlConnection = New SqlConnection(Data Source=localhost;Integrated Security=SSPI;Initial Catalog=pubs;)Dim logoCMD As SqlCommand = New SqlCommand(SELECT pub_id logo FROM pub_info pubsConn)Dim fs As FileStream Writes the BLOB to a file ( bmp) Dim bw As BinaryWriter Streams the binary data to the FileStream object Dim bufferSize As Integer = The size of the BLOB buffer Dim outbyte(bufferSize ) As Byte The BLOB byte() buffer to be filled by GetBytes Dim retval As Long The bytes returned from GetBytes Dim startIndex As Long = The starting position in the BLOB output Dim pub_id As String = The publisher id to use in the file name Open the connection and read data into the DataReader pubsConn Open()Dim myReader As SqlDataReader = logoCMD ExecuteReader(CommandBehavior SequentialAccess)Do While myReader Read() Get the publisher id which must occur before getting the logo pub_id = myReader GetString( ) Create a file to hold the output fs = New FileStream(logo & pub_id & bmp FileMode OpenOrCreate FileAccess Write)bw = New BinaryWriter(fs) Reset the starting byte for a new BLOB startIndex = Read bytes into outbyte() and retain the number of bytes returned retval = myReader GetBytes( startIndex outbyte bufferSize) Continue reading and writing while there are bytes beyond the size of the buffer Do While retval = bufferSizebw Write(outbyte)bw Flush() Reposition the start index to the end of the last buffer and fill the buffer startIndex = startIndex + bufferSizeretval = myReader GetBytes( startIndex outbyte bufferSize)Loop Write the remaining buffer bw Write(outbyte)bw Flush() Close the output file bw Close()fs Close()Loop Close the reader and the connection myReader Close()pubsConn Close()[C#]SqlConnection pubsConn = new SqlConnection(Data Source=localhost;Integrated Security=SSPI;Initial Catalog=pubs;);SqlCommand logoCMD = new SqlCommand(SELECT pub_id logo FROM pub_info pubsConn);FileStream fs; // Writes the BLOB to a file ( bmp) BinaryWriter bw; // Streams the BLOB to the FileStream object int bufferSize = ; // Size of the BLOB buffer byte[] outbyte = new byte[bufferSize]; // The BLOB byte[] buffer to be filled by GetBytes long retval; // The bytes returned from GetBytes long startIndex = ; // The starting position in the BLOB output string pub_id = ; // The publisher id to use in the file name // Open the connection and read data into the DataReader pubsConn Open();SqlDataReader myReader = logoCMD ExecuteReader(CommandBehavior SequentialAccess);while (myReader Read()){// Get the publisher id which must occur before getting the logo pub_id = myReader GetString( );// Create a file to hold the output fs = new FileStream(logo + pub_id + bmp FileMode OpenOrCreate FileAccess Write);bw = new BinaryWriter(fs);// Reset the starting byte for the new BLOB startIndex = ;// Read the bytes into outbyte[] and retain the number of bytes returned retval = myReader GetBytes( startIndex outbyte bufferSize);// Continue reading and writing while there are bytes beyond the size of the buffer while (retval == bufferSize){bw Write(outbyte);bw Flush();// Reposition the start index to the end of the last buffer and fill the buffer startIndex+= bufferSize;retval = myReader GetBytes( startIndex outbyte bufferSize);}// Write the remaining buffer bw Write(outbyte);bw Flush();// Close the output file bw Close();fs Close();}// Close the reader and the connection myReader Close();pubsConn Close(); lishixinzhi/Article/program/net/201311/12026
1 获取数据的方式
[1]DataReader 为在线 *** 作数据, DataReader会一直占用SqlConnection连接,在其获得数据过程中其它 *** 作不可以再使用SqlConnection连接对象。
代码如下:
while(datareaderread())
{
}
dataviewdatasource=datareader;
dataviewdatabind();
[2]DataSet为离线 *** 作数据,DataSet会将数据一次性读入内存,然后断开连接,这时其它 *** 作就可以使用SqlConnection连接对象。
后台代码如下:
public string test = "";
protected void Page_Load(object sender, EventArgs e)
{
DataSet ds=new DataSet();//这里是你的数据,我就不写了test = "<table>";
for (int i = 0; i < dsTables[0]Rows; i++)
{
test+="<tr><td>"+dsTables[0]Rows[i]["你要的字段"]ToString()+"</td></tr>"}
test+="</table>";
}
页面代码如下:
<form id="form1" runat="server">
<%=test %></form>
由于DataReader一次只读取一行数据,所以占用内存较小。但DataReader为只进且只读的,也就是只能单方向向前读取,如果你想回头去读取上一条数据是不允许的,并且不允许其修改数据。
由于DataSet一次性读取所有数据,所以比较消耗资源,但也提高了灵活性,在断开数据库连接情况下你可以对数据进行任何增删改查,按照任意的顺序读取数据,并可以将其写回到数据库。
有一点需要注意,DataReader一次读取一行并不意味着这时在数据库中的数据被修改,可以读到新的数据,这是数据库层面的保护
2.获取数据的机制
DataReader是通过IDbCommandExecuteReader来读取数据。
DataSet则是通过DbDataAdapterFill来填充数据。
所以DataReader在获取数据时不能关闭连接。而DataSet则可以,因为DbDataAdapter已经将数据读取到应用程序服务器中,所以在使用DataReader时一定要注意,及时关闭连接。
3.其它区别
DataReader读取速度快于DataSet。
DataReader是数据提供者类,DataSet是一般性类,借助于DbDataAdapter来填充数据。
因为DataSet是离线 *** 作数据,所以在事务中使用锁时要注意,因为DataSet填充数据后会断开连接,也就会释放锁。
4使用DataReader可以提高执行效率,有两种方式可以提高代码的性能:一种是基于序号的查找,一个是使用适当的Get方法来查找。
因为查询出来的结果一般都不会改变,除非再次改动查询语句,因此可以通过定位列的位置来查找记录。用这种方法有一个问题,就是可能知道一列的名称而不知道其所在的位置,这个问题的解决方案是通过调用DataReader 对象的GetOrdinal()方法,此方法接收一个列名并返回此列名所在的列号。例:
代码如下:
int id = readerGetOrdinal("CategoryName");while (readerRead())
{
ResponseWrite(readerGetInt32(0)ToString() + " " + readerGetString(1)ToString() + "<br />");
readerClose();
}
DataReader的GetInt32()和GetString()通过接收一个列号来返回一个列的值,这两种是最常用的,其中还有很多其它的类型。
注意:
DataReader对象在调用其 Close() 方法关闭 DataReader 对象,然后调用 SqlConnection 对象的 Close 方法关闭与数据库的连接,如果在没有关闭之前又重新打开第二个连接,则会产生一条异常信息,如:并发问题。使用完SqlDataReader后,可以在程序中显示的调用 数据库连接对象的 Close() 方法关闭连接,也可以在调用Command对象的ExecuteReader方法时传递 CommandBehaviorCloseConnection 这个枚举变量,这样在调用SqlDataReader的 Close 方法时会自动关闭数据库连接。
//未式关闭连接
public SysFunction GetModelById(string id)
{
SqlConnection conn = new SqlConnection(ConfigurationManagerConnectionStrings["sqlConStr"]ToString());
connOpen();
SqlCommand cmd = new SqlCommand("SELECT FROM SysFunction WHERE FunctionId =" + id, conn);
SqlDataReader dataReader = cmdExecuteReader();
SysFunction model = new SysFunction(); while (dataReaderRead())
{
modelFunctionName = dataReader["FunctionName"]ToString();
modelFunctionCode = dataReader["FunctionCode"]ToString();
}
dataReaderClose();
dataReaderDispose(); string drState = dataReaderIsClosedToString(); //True
string connState = connStateToString(); //Open
return model;
}
//调用Connection 对象的 Close() 方法显式关闭连接
public SysFunction GetModelById(string id)
{
SqlConnection conn = new SqlConnection(ConfigurationManagerConnectionStrings["sqlConStr"]ToString());
connOpen();
SqlCommand cmd = new SqlCommand("SELECT FROM SysFunction WHERE FunctionId =" + id, conn);
SqlDataReader dataReader = cmdExecuteReader();
SysFunction model = new SysFunction(); while (dataReaderRead())
{
modelFunctionName = dataReader["FunctionName"]ToString();
modelFunctionCode = dataReader["FunctionCode"]ToString();
}
dataReaderClose();
dataReaderDispose();
connClose(); //显式关闭连接
string drState = dataReaderIsClosedToString(); //True
string connState = connStateToString(); //Close
return model;
}
//调用Command 对象的 ExecuteReader() 方法时传递 CommandBehaviorCloseConnection 参数
public SysFunction GetModelById(string id)
{
SqlConnection conn = new SqlConnection(ConfigurationManagerConnectionStrings["sqlConStr"]ToString());
connOpen();
SqlCommand cmd = new SqlCommand("SELECT FROM SysFunction WHERE FunctionId =" + id, conn);
//执行该cmd时,如果关闭关联的 DataReader 对象,则关联的 Connection 对象也将关闭
SqlDataReader dataReader = cmdExecuteReader(CommandBehaviorCloseConnection);
SysFunction model = new SysFunction(); while (dataReaderRead())
{
modelFunctionName = dataReader["FunctionName"]ToString();
modelFunctionCode = dataReader["FunctionCode"]ToString();
}
dataReaderClose();
dataReaderDispose(); string drState = dataReaderIsClosedToString(); //True
string connState = connStateToString(); //Close
return model;
}
以上就是关于C#中读取数据库中Image数据全部的内容,包括:C#中读取数据库中Image数据、C#之 DataReader 和 DataSet 的区别、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)