C#修改DataReader默认行为

开发 后端
这里介绍C#修改DataReader默认行为,当访问 BLOB 字段中的数据时,请使用 DataReader 的 GetBytes 类型化访问器,该访问器将使用二进制数据填充 byte 数组。

学习C#时,经常会遇到C#修改DataReader默认行为问题,这里将介绍C#修改DataReader默认行为问题的解决方法。

DataReader默认行为是在整个数据行可用时立即以行的形式加载传入数据。但是,对于二进制大对象 (BLOB) 则需要进行不同的处理,因为它们可能包含数十亿字节的数据,而单个行中无法包含如此多的数据。Command.ExecuteReader 方法具有一个重载,它将采用 CommandBehavior 参数来用C#修改DataReader默认行为。您可以将 CommandBehavior.SequentialAccess 传递到 ExecuteReader 方法来用C#修改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。

C#修改DataReader默认行为的代码:

  1. Dim pubsConn As SqlConnection = New SqlConnection
    (Data 
    Source=localhost;Integrated Security=SSPI;Initial Catalog=pubs;)  
  2. Dim logoCMD As SqlCommand = New SqlCommand
    (SELECT pub_id, logo FROM pub_info, pubsConn)  
  3.  
  4. Dim fs As FileStream ' Writes the BLOB to a file (*.bmp).  
  5. Dim bw As BinaryWriter ' Streams the binary data to the FileStream object.  
  6.  
  7. Dim bufferSize As Integer = 100 ' The size of the BLOB buffer.  
  8. Dim outbyte(bufferSize - 1) As Byte ' The BLOB byte() 
    buffer to be filled by GetBytes.  
  9. Dim retval As Long ' The bytes returned from GetBytes.  
  10. Dim startIndex As Long = 0 ' The starting position in the BLOB output.  
  11.  
  12. Dim pub_id As String = ' The publisher id to use in the file name.  
  13.  
  14. ' Open the connection and read data into the DataReader.  
  15. pubsConn.Open()  
  16. Dim myReader As SqlDataReader = logoCMD.ExecuteReader
    (CommandBehavior.SequentialAccess)  
  17.  
  18. Do While myReader.Read()  
  19. ' Get the publisher id, which must occur before getting the logo.  
  20. pub_id = myReader.GetString(0)  
  21.  
  22. ' Create a file to hold the output.  
  23. fs = New FileStream(logo & pub_id & .bmp, FileMode.OpenOrCreate, FileAccess.Write)  
  24. bw = New BinaryWriter(fs)  
  25.  
  26. ' Reset the starting byte for a new BLOB.  
  27. startIndex = 0 
  28.  
  29. ' Read bytes into outbyte() and retain the number of bytes returned.  
  30. retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize)  
  31.  
  32. ' Continue reading and writing while there are bytes beyond the size of the buffer.  
  33. Do While retval = bufferSize 
  34. bw.Write(outbyte)  
  35. bw.Flush()  
  36.  
  37. ' Reposition the start index to the end of the last buffer and fill the buffer.  
  38. startIndexstartIndex = startIndex + bufferSize  
  39. retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize)  
  40. Loop  
  41.  
  42. ' Write the remaining buffer.  
  43. bw.Write(outbyte)  
  44. bw.Flush()  
  45.  
  46. ' Close the output file.  
  47. bw.Close()  
  48. fs.Close()  
  49. Loop  
  50.  
  51. ' Close the reader and the connection.  
  52. myReader.Close()  
  53. pubsConn.Close()  
  54. [C#]  
  55. SqlConnection pubsConn = new SqlConnection
    (Data 
    Source=localhost;Integrated Security=SSPI;Initial Catalog=pubs;);  
  56. SqlCommand logoCMD = new SqlCommand(SELECT pub_id, logo FROM pub_info, pubsConn);  
  57.  
  58. FileStream fs; 
  59. // Writes the BLOB to a file (*.bmp).  
  60. BinaryWriter bw; 
  61. // Streams the BLOB to the FileStream object.  
  62.  
  63. int bufferSize = 100
  64. // Size of the BLOB buffer.  
  65. byte[] outbyte = new byte[bufferSize]; 
  66. // The BLOB byte[] buffer to be filled by GetBytes.  
  67. long retval; // The bytes returned from GetBytes.  
  68. long startIndex = 0
  69. // The starting position in the BLOB output.  
  70.  
  71. string pub_id = ; 
  72. // The publisher id to use in the file name.  
  73.  
  74. // Open the connection and read data into the DataReader.  
  75. pubsConn.Open();  
  76. SqlDataReader myReader = logoCMD.ExecuteReader(CommandBehavior.SequentialAccess);  
  77.  
  78. while (myReader.Read())  
  79. {  
  80. // Get the publisher id, which must occur before getting the logo.  
  81. pub_id = myReader.GetString(0);  
  82.  
  83. // Create a file to hold the output.  
  84. fs = new FileStream(logo + pub_id + .bmp, FileMode.OpenOrCreate, FileAccess.Write);  
  85. bw = new BinaryWriter(fs);  
  86.  
  87. // Reset the starting byte for the new BLOB.  
  88. startIndex = 0;  
  89.  
  90. // Read the bytes into outbyte[] and retain the number of bytes returned.  
  91. retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);  
  92.  
  93. // Continue reading and writing while there are bytes beyond the size of the buffer.  
  94. while (retval == bufferSize)  
  95. {  
  96. bw.Write(outbyte);  
  97. bw.Flush();  
  98.  
  99. // Reposition the start index to the end of the last buffer and fill the buffer.  
  100. startIndex+= bufferSize;  
  101. retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);  
  102. }  
  103.  
  104. // Write the remaining buffer.  
  105. bw.Write(outbyte);  
  106. bw.Flush();  
  107.  
  108. // Close the output file.  
  109. bw.Close();  
  110. fs.Close();  
  111. }  
  112.  
  113. // Close the reader and the connection.  
  114. myReader.Close();  
  115. pubsConn.Close();  

【编辑推荐】

  1. C#泛型支持简单描述
  2. C#实现泛型类简单分析
  3. C# Singleton设计模式浅谈
  4. C#对接口成员访问分析
  5. C#实现插件构架浅析
责任编辑:佚名 来源: 博客园
相关推荐

2009-09-11 12:07:12

C# WinForm控

2021-01-28 05:14:40

C#接口签名

2009-08-28 16:19:30

C#实现修改动态链接库

2009-08-25 17:15:50

C#隐藏C#重写C#重载

2009-09-11 12:31:15

C# WinForm控设置默认值

2009-09-02 17:10:45

C#语言入门

2020-06-17 09:01:37

C语言代码开发

2009-08-25 17:21:31

C#索引

2009-08-27 16:11:03

C# delegateC# event

2009-08-25 17:59:49

C#入门

2009-08-13 17:04:09

C#语言C#程序

2011-04-07 09:40:57

DataReader链接关闭

2009-11-04 12:45:33

ADO.NET Dat

2011-04-07 09:20:12

DataReader关闭问题

2009-08-26 10:34:15

C#类型C#变量

2009-08-18 10:30:30

C#枚举

2009-08-24 11:02:52

C#接口映射

2009-08-19 16:50:32

Visual C#C#语言特性

2009-08-24 09:55:26

C#接口转换

2016-10-13 13:33:41

反射特性c#
点赞
收藏

51CTO技术栈公众号