Thursday, November 05, 2009

Getting Non-Null Data

UPDATE: See my new post on this topic. (I also corrected code in this current post, where I changed to test for null before testing for DBNull.Value ... it was an oversight on my part. Sorry, hope it didn't cause anyone problems).

I see questions along these lines all the time:

//I'm doing this:

int CustID = (int)dsCustomer.Tables["Customer"].Rows[0]["CustID"];

// It throws an exception because CustID is DBNull in the data.
// How do I handle this?


I have a CommonFunctions class that I use for things such as a GetNonNull( ) method (it's an old class, dating back to the 1.1 days, but it still works fine and so I have never updated it for 2.0, haven't really looked to see if it's even necessary).  This will work for any type of object, not just data in a DataSet, but is seems that DataSet access is  the commonly asked question.

This is implemented with many overloads, but here's an example of just a few:

public class CommonFunctions
{
public static object GetNonNull(object Test, object Default)
{
if (Test != null && Test != DBNull.Value)
return Test;
else
return Default;
}
public static string GetNonNull(object Test, string Default)
{
if (Test != null && Test != DBNull.Value)
{
if(Test is DateTime)
{
DateTime TestDT = Convert.ToDateTime(Test);
DateTime SqlNull = new DateTime(1900, 1, 1);

if(TestDT == SqlNull)
return Default;
}
else
if (Test is bool)
{
bool YesNo = Convert.ToBoolean(Test);
if (YesNo)
return "Yes";
else
return "No";
}

return Test.ToString().Trim();
}
else
return Default;
}
public static int GetNonNull(object Test, int Default)
{
if (Test != null && Test != DBNull.Value)
return Convert.ToInt32(Test);
else
return Default;
}
public static DateTime GetNonNull(object Test, DateTime Default)
{

if (Test != null && Test != DBNull.Value)
{
DateTime TestDT = Convert.ToDateTime(Test);
DateTime SqlNull = new DateTime(1900, 1, 1);
DateTime NetNull = new DateTime(1, 1, 1);

if(TestDT != SqlNull && TestDT != NetNull)
return TestDT;
else
return Default;
}
else
return Default;
}
}

These are just a sample of the overloads I use. I have a few more such as for bool, decimal, long and even a few differently named methods specifically for Dates, such as these next two:

public static string GetNonNullDate(object Test, string Default)
{
if (Test != null && Test != DBNull.Value)
{
if(Test is DateTime)
{
DateTime TestDT = Convert.ToDateTime(Test);
DateTime SqlNull = new DateTime(1900, 1, 1);

if(TestDT != SqlNull)
return TestDT.ToShortDateString();
}

return Default;
}
else
return Default;
}
public static DateTime GetNonNullDate(object Test)
{
if (Test != null && Test != DBNull.Value && Test is DateTime)
return Convert.ToDateTime(Test);
else
return new DateTime(1900, 1, 1);
}


Anyway, you get the point. Note that these are static methods, so no instantiation of the CommonFunctions class is necessary.To use them, you would simply have something like this:

int MyInt = CommonFunctions.GetNonNull(MyDataSet.Tables[0].Rows[0]["MyColumn"], 0);

// -or-

DateTime MyDatetime = CommonFunctions.GetNonNullDate(MyDataSet.Tables[0].Rows[0]["MyDateColumn"])


3 comments:

  1. I had the very same issue that you posted about, Used an IIF with VB.NET to check if the data object's value was null, if so return an empty string, else return the dataRow object.

    ReplyDelete
  2. This class expands on that, in that it doesn't assume that you should return an empty string if the column contains a DBNull.Value ... it lets you specify a default value.

    Did you have an actual class defined for doing this, or do you have these IIF scattered about in your code? In actuality, you don't need to do that for an empty string, because the .ToString() method for your object will automatically return an empty string if the object contains DBNull.Value (but, not if it's actually null, or Nothing in VB).

    ReplyDelete
  3. This post has been updated: minor changes if you're interested.

    ReplyDelete