Scott Van Vliet

Less Talk, More Rock

June 2008 - Posts

IDataReader Extension Methods

First of all -- I'm a total liar.  I was supposed to offer up some great insight from Tech•Ed.  But alas, I had to leave early and fly to Seattle for a meeting.  So, I wasn't able to share any fun stuff :(

We'll, I actually have a tiny bit of time to write, and I thought I'd share the result of recent code review.

I'm currently teaching .NET (Framework fundamentals, C#, et al.) to some of my clients who are preparing to take over the support of a very large application (we're going on 2 years of development and deployment!) As we were looking at some of the code, I came across some stuff from our offshore team that slipped by my team's radar. In this particular project, we found hundreds of lines that looked like this:

theatre.ID = (reader["theatre_id"] is DBNull) ?
   
0 : Convert.ToInt32(reader["theatre_id"]);

theatre.Code = (reader["theatre_code"] is DBNull) ?
   
String.Empty : reader["theatre_code"].ToString();

Ick!  I was very bummed to come across this while teaching my clients about best practice -- was a bit 'the fool'.  Not wanting to let this pass, I quickly redirected the discussion to talk about refactoring and reuse (which was kind of a nice segue to some OO topics.)  In this discussion, we wrote an Extension Method to the IDataReader class to clean-up this code.  The new code looked pretty:

theatre.ID = reader.GetValueOrDefault<int>("theatre_id");

theatre.Code = reader.GetValueOrDefault<string>("theatre_code");

The details of this Extension Method are as follows:

/// <SUMMARY>
/// Contains extension methods for the IDataReader interface.
/// </SUMMARY>
public static class DataReaderExtender
{
  /// <SUMMARY>
  /// This method will return the value of the specified columnName, cast to
  /// the type specified in T. However, if the value found in the reader is
  /// DBNull, this method will return the default value of the type T.
  /// </SUMMARY>
  /// <TYPEPARAM name="T">The type to which the value found in the reader should be cast.</TYPEPARAM>
  /// <PARAM name="reader">The reader in which columnName is found.</PARAM>
  /// <PARAM name="columnName">The columnName to retrieve.</PARAM>
  /// <RETURNS>The column value within the reader typed as T.</RETURNS>
 
public static T GetValueOrDefault<T>(this IDataReader reader, string columnName)
  {
   
object columnValue = reader[columnName];
    T returnValue = default(T);
    if (!(columnValue is DBNull))
    {
     
returnValue = (T)Convert.ChangeType(columnValue, typeof(T));
    }
    return returnValue; 
  
}
}

Enjoy! (I've posted the code here: DataReaderExtender.zip)

Hello from Tech·Ed

Hey everyone -- just got out of the Tech·Ed 2008 keynote and learned that this was Bill's last keynote as chairman of Microsoft... kind of cool to witness.  Was a good session, outlining SQL Server Data Services and some other stuff -- but nothing "new", per se.  But hopefully we'll see some good stuff in the sessions...

 I'm off to a WPF session, and will be posting some tibdits as I find them.  Talk soon.

More Posts