A Type Safe IDataReader Wrapper

I don’t always use NHibernate… it’s true… in fact, plain old ADO.NET, DataSets, DataTables and IDataReaders can offer some nice advantages when used in the right way at the right time. Today, I found myself writing more IDataReader code and getting tired of having to get the ordinal, check for dbnull, and then retrieve the data. So, I wrote a quick wrapper around that functionality, giving me the specific types of data that I want based on my column name. I know this has been done a thousand times before, but I wanted to share anyways. It’s not “complete” if you’re looking for all of the IDataReader functionality. It fills my current needs, though, and is easy to extend when you need to.

   1: public class TypeSafeDataReaderWrapper

   2: {

   3:     private readonly IDataReader dataReader;

   4:  

   5:     public TypeSafeDataReaderWrapper(IDataReader dataReader)

   6:     {

   7:         this.dataReader = dataReader;

   8:     }

   9:  

  10:     public bool GetBoolean(string columnName)

  11:     {

  12:         return GetValue<bool>(columnName);

  13:     }

  14:  

  15:     public int GetInt32(string columnName)

  16:     {

  17:         return GetValue<int>(columnName);

  18:     }

  19:  

  20:     public string GetString(string columnName)

  21:     {

  22:         return GetValue<string>(columnName);

  23:     }

  24:  

  25:     public decimal GetDecimal(string columnName)

  26:     {

  27:         return GetValue<decimal>(columnName);

  28:     }

  29:  

  30:     private T GetValue<T>(string columnName)

  31:     {

  32:         T value = default(T);

  33:         int columnIndex = dataReader.GetOrdinal(columnName);

  34:         if (columnIndex > -1)

  35:         {

  36:             if (!dataReader.IsDBNull(columnIndex))

  37:             {

  38:                 value = (T) dataReader.GetValue(columnIndex);

  39:             }

  40:         }

  41:         return value;

  42:     }

  43: }


Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in .NET, C#, Data Access, Design Patterns, Pragmatism. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.agilification.com Jeff Doolittle

    Is it a wrapper or a decorator? May want to fix the ctor.

  • http://www.agilification.com Jeff Doolittle

    Also, what about making these extension methods of IDataReader?

  • http://www.lostechies.com/members/derick.bailey/default.aspx derick.bailey

    @jeff,

    yeah, it certainly could be extension methods on IDataReader. that may make more sense, now that you suggest it.

    i fixed the constructor, too. it started as a Decorator but then I realized that I was not following that pattern’s intent well enough, so I renamed it in the blog post and missed the constructor name. :)

  • Travis

    http://fluentado.codeplex.com/

    Another small step between IDataReader and full blown ORM.

  • Steve

    If this class encapsulates a data reader then your class itself is going to have to implement IDisposable to dispose the data reader, etc. http://www.codeproject.com/KB/database/NullableReaders.aspx

    Also, you can cache the column names in an internal dictionary and actually get *faster* results than a data reader because you don’t have to look up the ordinal every single time when iterating over large result sets.

  • http://www.lostechies.com/members/derick.bailey/default.aspx derick.bailey

    @travis,

    we have something similar to fluent ado… not quite as full featured, but it suits our needs quite nicely.

    @steve,

    I’m not trying to encapsulate the the data reader, entirely – that’s why i’m not implementing IDataReader for this object. I’m going to convert this to extension methods, too, as @jeff suggested.

    i like the caching idea for the name lookups! that will definitely help for large data sets (which we have)

  • http://www.iDevForFun.com Jason

    I posted something similar on my blog just a few months ago … its an extension method and also deals with nullables.

    ///

    /// Get the value of a table column from a reader object
    ///

    /// Type of expected return value
    /// Reader oject to get the value from /// Name of column to retrieve the value from /// Column Value
    /// If T is not nullable and the column value is null
    public static T GetColumnValue(this IDataReader reader, string columnName)
    {
    if (reader.IsDBNull(reader.GetOrdinal(columnName)))
    {
    if (
    (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>))
    || typeof(T) == typeof(string)
    )
    {
    return default(T);
    }
    else throw new NullReferenceException(“DB Value is null”);
    }
    else return (T)reader[columnName];
    }

  • http://www.blogcoward.com jdn

    Hey, thanks for this. I remembered reading this post when it came out and was able to use it for something today.