views:

131

answers:

2

I'm working with an older Oracle database, and I feel there's likely a better way to go about unboxing the values I retrieve from the database.

Currently, I have a static class full of different type-specific methods:

public static int? Int(object o)
{
    try
    {
     return (int?)Convert.ToInt32(o);
    }
    catch (Exception)
    {
     return null;
    }
}

..and so on for different types, but I feel there should be a better way? If I want to unbox a value, I do something along the lines of...

int i;
i = nvl.Int(dataRow["column"]); //In this instance, "column" is of a numeric database type

I thought about using a generic class to handle all the different types, but I couldn't really figure out the best way to go about that.

Any ideas?

+4  A: 

I find helper methods such as the following useful in your scenario - testing for DBNull is more efficient than catching an Exception as in your example:

public static MyHelper
{
    public static Nullable<T> ToNullable<T>(object value) where T : struct
    {
        if (value == null) return null;
        if (Convert.IsDBNull(value)) return null;
        return (T) value;
    }

    public static string ToString(object value)
    {
        if (value == null) return null;
        if (Convert.IsDBNull(value)) return null;
        return (string)value;
    }
}

This works for the string and the usual primitive value types you will encounter (int, decimal, double, bool, DateTime).

It's slightly different from your example in that it casts rather than converts - but personally I prefer this. I.e. if the database column is NUMERIC (decimal), I'd rather be explicit if I wanted to convert the value to int, e.g.:

int? myIntValue = (int?) MyHelper.ToNullable<decimal>(reader["MyNumericColumn"]);
Joe
That's great, Joe, thanks. I'm sorry for my ignorance, but I'm not terribly clear on the first line: public static Nullable<T> ToNullable<T>(object value) where T : struct In particular, the "Nullable<T>" followed by the "ToNullable<T>" part. Is this a shorthand method for creating class/method?
Jesse
It's a method declaration: to make this clearer I've added a class declaration (class MyHelper) to the sample. "Nullable<T>" is the return type of the method, and "ToNullable<T>" is the name of the method. You replace "T" by any type, constrained by the fact that it must be a value type or struct (where T : struct). Hence if you call the method with the type decimal (ToNullable<decimal>) the return type will be Nullable<decimal> aka "decimal?". Hope that's a bit clearer.
Joe
Ah, I wasn't familiar with the "Nullable" class you had used., thanks Joe. I appreciate it.
Jesse
A: 

You could introduce simple model classes and map between them.

For example:

public class Customer
{
   public Customer(DataRow row) 
   {
      Name = row["Name"];
   }
   public Name { get; private set; }
}

Of course, to reduce duplicate code, you could create a base class for your model data classes.

Depending on effort you want to spend, you could go and use an ORM mapper NHibernate.

Dominik Fretz