Sunday, February 4, 2007

Trust in ADO.NET

In reviewing some C# code for a project at work, I'm constantly running across the following construct in the code (and this is from different developers, not just one):


DataSet ds = SqlHelper.ExecuteDataSet(sConn, CommandType.StoredProc, sProc, aParams);
// ... snip ...
DataRow row = ds.Tables[0].Rows[0];
int someInt = Int32.Parse(row["intColumn"].ToString());


Now, while this code works like you would expect, there's still something wrong with it. You're basically wasting cycles on mindless conversions.

Whenever you use ADO.NET DataRow objects, it is true that the return from the indexer is a generic Object, so something needs to happen to get the result into a strongly-typed value. But, if the database column is a SQL int, ADO.NET already returned you an Int32!

What's written above is basically the same as this:


int a = 1;
int b = Int32.Parse(a.ToString());


You're wasting cycles first converting the Int32 to a String and then using Int32.Parse to get it back to the Int32 that it was in the first place. Trust in ADO.NET!


DataSet ds = SqlHelper.ExecuteDataSet(sConn, CommandType.StoredProc, sProc, aParams);
// ... snip ...
DataRow row = ds.Tables[0].Rows[0];
int someInt = (int)row["intColumn"];


There we go, much better. If you want something that feels a little "safer" than a direct cast, feel free to use Convert.ToInt32; it at least knows not to waste time doing needless conversions if it's already passed an Int32.

As a final thought, I'll leave you this completely failed code to think about:


DataSet ds = SqlHelper.ExecuteDataSet(sConn, CommandType.StoredProc, sProc, aParams);
// ... snip ...
DataRow row = ds.Tables[0].Rows[0];
bool someBool = (row["bitColumn"].ToString() == "1");


(Hint: The reason this code didn't work like the developer expected is because the DataRow already returned a Boolean.)

No comments: