Well, finding this state of affairs unacceptable, I decided to rectify it. I expected it to be either difficult or annoying depending on the solution I accepted. First, I decided that it should be an extension method because I love extension methods and the fluency they provide. I also decided that it should be generic so you could have one method and specify the desired type. The tough decision came when I was trying to figure out how to handle all of the conversions between types.
Should I switch on the generic type and call the associated method on the SqlDataReader? That is to say, if you call GetValue
Then, I was looking around in the .net classes and found System.Convert.ChangeType and it made the whole process considerably easier. We also had a need to attempt to return the value as a specified type without throwing an exception if it failed (like int.TryParse) so I included a TryGetValue method as well.
public static T GetValue<T>(this SqlDataReader reader, string name)
{
return (T)Convert.ChangeType(reader[name], typeof(T));
}
public static bool TryGetValue<T>(this SqlDataReader reader, string name, out T output)
{
try
{
output = reader.GetValue<T>(name);
return true;
}
catch (Exception ex)
{
if (ex is InvalidCastException || ex is FormatException || ex is OverflowException)
{
output = default(T);
return false;
}
else
throw;
}
}
// usage examples
// string testString;
// bool result = reader.TryGetValue<string>("ColumnName", out testString);
// int testInt;
// bool result = reader.TryGetValue<int>("ColumnName", out testInt);
// int i = reader.GetValue<int>("ColumnName");
// string s = reader.GetValue<string>("ColumnName");
// DateTime dt = reader.GetValue<datetime>("ColumnName");
No comments:
Post a Comment