Reading Data with the SqlDataReader

A SqlDataReader is a type that is good for reading data in the most efficient manner possible.  You can *not* use it for writing data.  SqlDataReaders are often described as fast-forward firehose-like streams of data.<?XML:NAMESPACE PREFIX = O />

SqlDataReader是對於大多數有效的情況下讀取數據的好的方式。你不能使用它來寫入數據。SqlDataReaders通常作爲快速的只向前讀的數據流。

You can read from SqlDataReader objects in a forward-only sequential manner.  Once you've read some data, you must save it because you will not be able to go back and read it again.

你能夠以只向前的順序方式從SqlDataReader對象中進行讀取。只要你已經讀取了某些數據,你必須保存它們,因爲你將不能夠返回並再一次讀取它。

The forward only design of the SqlDataReader is what enables it to be fast.  It doesn't have overhead associated with traversing the data or writing it back to the data source.  Therefore, if your only requirement for a group of data is for reading one time and you want the fastest method possible, the SqlDataReader is the best choice.  Also, if the amount of data you need to read is larger than what you would prefer to hold in memory beyond a single call, then the streaming behavior of the SqlDataReader would be a good choice.

SqlDataReader的只向前讀的設計使它很迅速。它並沒有遍歷數據或者將數據重新寫回給數據源的負擔。因此,如果你一次只需要讀一組數據,並且希望最快速的方法,SqlDataReader則是最好的選擇。同樣,如果一個單獨調用所需要讀取的數據量大於內存的存放能力,SqlDataReader的數據流形式應該是一個好的選擇。

Note:  Observe that I used the term "one time" in the previous paragraph when discussing the reasons why you would use a SqlDataReader.  As with anything, there are exceptions.  In many cases, it is more efficient to use a cached DataSet.  While caching is outside the scope of this tutorial, we will discuss using DataSet objects in the next lesson.

注意:當討論爲什麼應該使用SalDataReader的時候,我在上一段中使用的術語“一次”。任何事情,都有異常發生。在一些情況下,更有效的是使用緩存DataSet。因爲緩存超出了本指南的範疇,我們將在下一節課“使用DataSet對象”中討論它。

Creating a SqlDataReader Object

創建SqlDataReader對象

Getting an instance of a SqlDataReader is a little different than the way you instantiate other ADO.NET objects.  You must call ExecuteReader on a command object, like this:

得到SqlDataReader對象於實例化其它ADO.NET對象稍微有些不同。你必須對一個command對象調用ExecuteReaer方法,比如這樣:

    SqlDataReader rdr = cmd.ExecuteReader();

The ExecuteReader method of the SqlCommand object, cmd , returns a SqlDataReader instance.  Creating a SqlDataReader with the new operator doesn't do anything for you.  As you learned in previous lessons, the SqlCommand object references the connection and the SQL statement necessary for the SqlDataReader to obtain data.

SqlCommand對象cmdExecuteReader方法返回一個SqlDataReader實例。使用new關鍵字創建一個SqlDataReader並不做任何事情。前面的課程已經學到,SqlCommand對象引用connectionSQL語句對於SqlDataReader讀取數據是必需的。

Reading Data

讀取數據

Previous lessons contained code that used a SqlDataReader, but the discussion was delayed so we could focus on the specific subject of that particular lesson.  This lesson builds from what you've seen and explains how to use the SqlDataReader.

前面的課程包含了使用SqlDataReader的代碼,但是關於前面課程中的細節的討論我們推遲了。這節課建立自你所見到的並解釋如何使用SqlDataReader

As explained earlier, the SqlDataReader returns data via a sequential stream.  To read this data, you must pull data from a table row-by-row.  Once a row has been read, the previous row is no longer available.  To read that row again, you would have to create a new instance of the SqlDataReader and read through the data stream again.

前面已經解釋了,SqlDataReader通過順序數據流返回數據。爲了讀取這些數據,你必須從一個表中一行一行的取出數據。只要一行被讀取,之前的數據就不再有效。爲了再次讀取那行,你應該創建一個新的SqlDataReader實例並且再次從數據流中讀取它。

The typical method of reading from the data stream returned by the SqlDataReader is to iterate through each row with a while loop.  The following code shows how to accomplish this:

SqlDataReader中讀取返回的數據流的典型方法是通過while循環迭代沒一行。下面的代碼顯示瞭如何完成:

        while (rdr.Read())

        {

               // get the results of each column

               string contact = (string)rdr["ContactName"];

               string company = (string)rdr["CompanyName"];

               string city    = (string)rdr["City"];

 

               // print out the results

               Console.Write("{0,-25}", contact);

               Console.Write("{0,-20}", city);

               Console.Write("{0,-25}", company);

               Console.WriteLine();

        }

Notice the call to Read on the SqlDataReader, rdr, in the while loop condition in the code above.  The return value of Read is type bool and returns true as long as there are more records to read.  After the last record in the data stream has been read, Read returns false.

注意在上面代碼中的while循環對SqlDataReader對象rdr調用的Read方法。Read方法的返回值爲bool,並且只要有記錄讀取就返回真。在數據流中所有的最後一條記錄被讀取了,Read方法就返回false

In previous lessons, we extracted the first column from the row by using the SqlDataReader indexer, i.e. rdr[0].  You can extract each column of the row with a numeric indexer like this, but it isn't very readable.  The example above uses a string indexer, where the string is the column name from the SQL query (the table column name if you used an asterisk, *.  String indexers are much more readable, making the code easier to maintain.

在前面的課程中,我們使用SqlDataReader的索引器,比如rdr[0],提取行中的第一列。你能夠使用諸如這樣的數值索引器提取行中的列,但是它並不具有很好的可讀性。上面的例子使用了字符串索引器,這裏的字符串是從SQL查詢語句中得到的列名(表的列名如果你使用一個星號,*.字符串下標具有更好的可讀性,使得代碼能夠更好的維護。

Regardless of the type of the indexer parameter, a SqlDataReader indexer will return type object.  This is why the example above casts results to a string.  Once the values are extracted, you can do whatever you want with them, such as printing them to output with Console type methods.

無論索引器參數是什麼類型,一個SqlDataReader索引器將返回object類型。這就是爲什麼上面要將結果轉換爲string的原因。只要值被提取,你能夠對它們爲所欲爲,比如使用Console類型的方法將它們打印到輸出。

Finishing Up

完結

Always remember to close your SqlDataReader, just like you need to close the SqlConnection.  Wrap the data access code in a try block and put the close operation in the finally block, like this:

一定要記住關閉SqlDataReader,就像關閉SqlConnection一樣。將數據存取代碼用try語句塊包圍起來,並把關閉操作放到finally語句塊中,就像這樣:

        try

        {

               // data access code

        }

        finally

        {

               // 3. close the reader

               if (rdr != null)

               {

                       rdr.Close();

               }

 

               // close the connection too

        }      

The code above checks the SqlDataReader to make sure it isn't null.  After the code knows that a good instance of the SqlDataReader exists, it can close it.  Listing 1 shows the code for the previous sections in its entirety.

上面的代碼檢測SqlDataReader,確保它不爲空。在代碼知道SqlDataReader的一個完好的實例存在,它就能夠關閉它。Listing1完整的顯示了前面各節的代碼。

Listing 1: Using the SqlDataReader

using System;

using System.Data;

using System.Data.SqlClient;

 

namespace Lesson04

{

        class ReaderDemo

        {

               static void <?XML:NAMESPACE PREFIX = ST1 />Main()

               {

                       ReaderDemo rd = new ReaderDemo();

                       rd.SimpleRead();

               }

 

               public void SimpleRead()

               {

                       // declare the SqlDataReader, which is used in

                       // both the try block and the finally block

                       SqlDataReader rdr = null;

 

                       // create a connection object

                       SqlConnection conn = new SqlConnection(

"Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI");

 

                       // create a command object

                       SqlCommand cmd  = new SqlCommand(

                               "select * from Customers", conn);

 

                       try

                       {

                               // open the connection

                               conn.Open();

 

                               // 1.  get an instance of the SqlDataReader

                               rdr = cmd.ExecuteReader();

 

                               // print a set of column headers

                               Console.WriteLine(

"Contact Name             City                Company Name");

                               Console.WriteLine(

"------------             ------------        ------------");

 

                               // 2.  print necessary columns of each record

                               while (rdr.Read())

                               {

                                      // get the results of each column

                                      string contact = (string)rdr["ContactName"];

                                      string company = (string)rdr["CompanyName"];

                                      string city    = (string)rdr["City"];

 

                                      // print out the results

                                      Console.Write("{0,-25}", contact);

                                      Console.Write("{0,-20}", city);

                                      Console.Write("{0,-25}", company);

                                      Console.WriteLine();

                               }

                       }

                       finally

                       {

                               // 3. close the reader

                               if (rdr != null)

                               {

                                      rdr.Close();

                               }

 

                               // close the connection

                               if (conn != null)

                               {

                                      conn.Close();

                               }

                       }      

               }

        }

}

 

Summary

總結

SqlDataReader objects allow you to read data in a fast forward-only manner.  You obtain data by reading each row from the data stream.  Call the Close method of the SqlDataReader to ensure there are not any resource leaks. 

SqlDataReader對象允許你以一種快速的只向前的方式讀取數據。你從數據流中讀取每一行來讀取數據。調用SqlDataReaderClose方法保證資源泄漏不會發生。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章