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