15.02.2015 Views

C# 4 and .NET 4

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

834 ❘ ChaPTer 30 cOre AdO.net<br />

As an aside, the numeric indexer took on average 0.09 seconds for the million accesses, <strong>and</strong> the textual<br />

one 0.63 seconds. The reason for this difference is that the textual method looks up the column number<br />

internally from the schema <strong>and</strong> then accesses it using its ordinal. If you know this information beforeh<strong>and</strong>,<br />

you can do a better job of accessing the data.<br />

So, should you use the numeric indexer Maybe, but there is a better way. In addition to the indexers just<br />

presented, OleDbDataReader has a set of type-safe methods that can be used to read columns. These are<br />

fairly self-explanatory, <strong>and</strong> all begin with Get. There are methods to read most types of data, such as<br />

GetInt32, GetFloat, GetGuid, <strong>and</strong> so on.<br />

The million iterations using GetInt32 took 0.06 seconds. The overhead in the numeric indexer is incurred<br />

while getting the data type, calling the same code as GetInt32, then boxing (<strong>and</strong> in this instance unboxing)<br />

an integer. So, if you know the schema beforeh<strong>and</strong>, are willing to use cryptic numbers instead of column<br />

names, <strong>and</strong> can be bothered to use a type-safe function for each <strong>and</strong> every column access, you st<strong>and</strong> to gain<br />

somewhere in the region of a tenfold speed increase over using a textual column name (when selecting those<br />

million copies of the same column).<br />

Needless to say, there is a tradeoff between maintainability <strong>and</strong> speed. If you must use numeric indexers,<br />

define constants within class scope for each of the columns that you will be accessing. The preceding code<br />

can be used to select data from any OLE DB database; however, there are a number of SQL Server–specific<br />

classes that can be used with the obvious portability tradeoff.<br />

The following example is the same as the previous one, except that in this instance the OLE DB provider<br />

<strong>and</strong> all references to OLE DB classes have been replaced with their SQL counterparts. The example is<br />

located in the 04_DataReaderSql directory:<br />

using System;<br />

using System.Data.SqlClient;<br />

public class DataReaderSql<br />

{<br />

public static int Main(string[] args)<br />

{<br />

string source = "server=(local);" +<br />

"integrated security=SSPI;" +<br />

"database=northwind";<br />

string select = "SELECT ContactName,CompanyName FROM Customers";<br />

SqlConnection conn = new SqlConnection(source);<br />

conn.Open();<br />

SqlComm<strong>and</strong> cmd = new SqlComm<strong>and</strong>(select, conn);<br />

SqlDataReader aReader = cmd.ExecuteReader();<br />

while(aReader.Read())<br />

Console.WriteLine("'{0}' from {1}", aReader.GetString(0),<br />

aReader.GetString(1));<br />

aReader.Close();<br />

conn.Close();<br />

return 0;<br />

}<br />

}<br />

code download DataReaderSql.cs<br />

Notice the difference If you’re typing this, do a global replace on OleDb with Sql, change the data source<br />

string, <strong>and</strong> recompile. It’s that easy!<br />

The same performance tests were run on the indexers for the SQL provider, <strong>and</strong> this time the numeric<br />

indexers were both exactly the same at 0.13 seconds for the million accesses, <strong>and</strong> the string-based indexer<br />

ran at about 0.65 seconds.<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!