Reading Data Using a DataReader

370 Set up a data adapter object. Dim strSelect As String = SELECT FROM Customers WHERE City = London Dim da As New SqlDataAdapterstrSelect, cn Load a data set. Dim ds As New DataSetLondonCustomersDataSet da.Fillds, LondonCustomers Close the database connection. cn.Close Save as XSD. ds.WriteXmlSchemac:\LondonCustomersDataSet.xsd Next, run Microsofts XML Schema Definition Tool xsd.exe against the XML schema file you just generated. Here is the command line used for the LondonCustomers DataSet: xsd d l:VB LondonCustomersDataSet.xsd The d option indicates that a custom DataSet and related classes should be created. The l:VB option specifies that the generated source code should be written in Visual Basic .NET the tool is also able to generate C source code. With this command line, the tool generates a file named LondonCustomersDataSet.vb, which contains the source code. Finally, add the generated .vb file to a project and make use of its classes.

8.11 Reading Data Using a DataReader

As you have seen, the DataSet class provides a flexible way to read and write data in any data source. There are times, however, when such flexibility is not needed and when it might be better to optimize data-access speed as much as possible. For example, an application might store the text for all of its drop-down lists in a database table and read them out when the application is started. Clearly, all that is needed here is to read once through a result set as fast as possible. For needs such as this, ADO.NET has DataReader classes. Unlike the DataSet class, DataReader classes are connected to their data sources. Consequently, there is no generic DataReader class. Rather, each managed provider exposes its own DataReader class, which implements the System.Data.IDataReader interface. The SQL Server managed provider exposes the SqlDataReader class in the System.Data.SqlClient namespace. DataReader classes provide sequential, forward-only, read-only access to data. Because they are optimized for this task, they are faster than the DataSet class. Ex am ple 8- 12 shows how to read through a result set using an SqlDataReader object. Example 8-12. Using a SqlDataReader object Open a database connection. Dim strConnection As String = _ Data Source=localhost;Initial Catalog=Northwind; _ Integrated Security=True Dim cn As SqlConnection = New SqlConnectionstrConnection cn.Open Set up a command object. Dim strSql As String = SELECT FROM Customers _ WHERE Country = Germany Dim cmd As New SqlCommandstrSql, cn 371 Set up a data reader. Dim rdr As SqlDataReader rdr = cmd.ExecuteReader Use the data. Do While rdr.Read Console.WriteLinerdrCompanyName Loop Close the database connection. cn.Close Opening a connection to the database is done the same as when using a DataSet object. However, with a DataReader object, the connection must remain open while the data is read. Instead of an SqlDataAdapter object, an SqlCommand object is used to hold the command that will be executed to select data from the database. The SqlCommand classs ExecuteReader method is called to execute the command and to return an SqlDataReader object. The SqlDataReader object is then used to read through the result set. Note the Do While loop in Ex am ple 8- 12 , repeated here: Do While rdr.Read Console.WriteLinerdrCompanyName Loop Developers who are used to coding against classic ADO will note that this loop appears to lack a move to the next row statement. However, it is there. The SqlDataReader classs Read method performs the function of positioning the SqlDataReader object onto the next row to be read. In classic ADO, a RecordSet object was initially positioned on the first row of the result set. After reading each record, the RecordSet objects MoveNext method had to be called to position the RecordSet onto the next row in the result set. Forgetting to call MoveNext was a common cause of infinite loops. Microsoft removed this thorn as follows: • The DataReader object is initially positioned just prior to the first row of the result set and therefore has to be repositioned before reading any data. • The Read method repositions the DataReader to the next row, returning True if the DataReader is positioned onto a valid row and False if the DataReader is positioned past the last row in the result set. These changes result in tight, easy-to-write loops such as the one in Ex am ple 8- 12 . The DataReader provides an Item property for reading column values from the current row. The Item property is overloaded to take either an integer that specifies the column number, which is zero-based, or a string that specifies the column name. The Item property is the default property of the SqlDataReader class, so it can be omitted. For example, this line: Console.WriteLinerdrCompanyName is equivalent to this line: Console.WriteLinerdr.ItemCompanyName

8.12 Executing Stored ProceduresThrough a SqlCommand Object