In many code reviews, I have seen we miss out proper object parsing from SqlReader or end up with repeated lengthy codes or there is no fail safe mechanism to handle, if parse fails out. I will be extending an approach that I have been using in dynamic forms for parsing to make it compatible with reader object. Also, covering up above short comings with extension methods in generic way and common method for achieving same.The codes are based on Int.TryParse and similar methods. It was introduced in 2.0 Framework, so the code should be compatible with 2.0 or higher framework. Let’s directly dive into usage since we have just single function DbTryParse. I will be explaining function in later stage. We can use with fail safe mechanism where some values are not properly parsed then row will get skipped or in normal way, we define some default value and move ahead with other rows. |
int id; string val; double dbl; reader[“id”].DbTryParse(out id, int.TryParse, 89); reader[“val”].DbTryParse(out val, “NA”); reader[“doubleTest”].DbTryParse(out dbl, double.TryParse); I have tried with integer, string and double in simailar way other types of variable can be used as well. In this I am reading integer Id column and sending logic for parsing with int.TryParse. If parse fails then it will set 100 as a default, this is optional parameter. Check out double parsing where we are not setting the default value. reader[“id”].DbTryParse(out id, int.TryParse, 100) Since we do not have function like TryParse for string and it’s a reference type, there is no need for same and it is implemented in different way that we will see it later. reader[“val”].DbTryParse(out val, “NA”); If we want to skip rows on failure of any parse, then we could use: |
if (reader["id"].DbTryParse(out id, int.TryParse) && reader["val"].DbTryParse(out val) && reader["doubleTest"].DbTryParse(out dbl, double.TryParse)) { Console.WriteLine("Parsing successful"); } else { Console.WriteLine("Parsing failed."); }
That is all we need for parsing. The single DbTryParse is taking care of every possible parses.
Let’s look into the implementation part. If we see all TryParse from .Net they accept string as first parameter and then the out parameter to parse. For that a TryParseHandler delegate wrapper is created. The parse functions generic are restricted with struct type which takes of value type. The same function is overloaded to handle string type.
Here are the codes:
public static class CommonExtensionMethods { /// /// Try parse handler /// ///The result type ///The string literal. ///The result of typecasting. ///True, if typecasting is successful, else false. public delegate bool TryParseHandler(string value, out T result); /// /// Generic try parse. /// ///Type of the value ///The string literal. ///The parsed value. ///The type casting handler. ///The default value. This value will be set in case of failed parsing. ///Parsed object ///handler public static bool TryParse(thisstring value, out T parsedValue, TryParseHandler handler, T defaultValue = default(T)) where T : struct { if (handler == null) { throw new ArgumentNullException("handler"); } if (String.IsNullOrEmpty(value)) { parsedValue = defaultValue; returnfalse; } return handler(value, out parsedValue); } /// /// Generic try parse for databases object. /// ///The type of object for parsing value ///The value. ///The parsed value. ///The parsing handler. ///The default value. This value will be set in case of failed parsing. /// /// Parsed object /// public static bool DbTryParse(thisobject val, out T parsedValue, TryParseHandler handler , T defaultValue = default(T)) where T : struct { if (val == DBNull.Value) { parsedValue = defaultValue; return false; } return Convert.ToString(val).TryParse(out parsedValue, handler, defaultValue); } /// /// Databases object parsing to string. /// ///The value. ///The parsed value. ///The default value. This value will be set in case of failed parsing. ///String representation of parsed object public static bool DbTryParse(thisobject val, outstring parsedValue , string defaultValue = null) { if (val == DBNull.Value) { parsedValue = defaultValue; return false; } parsedValue = Convert.ToString(val) ?? defaultValue; return parsedValue == defaultValue ? false : true; } /// /// Databases object parsing to string. /// ///The value. ///The default value. This value will be set in case of failed parsing. ///String representation of given object public static string DbParse(thisobject val, string defaultValue = null) { return val == DBNull.Value ? defaultValue : Convert.ToString(val) ?? defaultValue; } }
Modify codes are per your need and please write in comments if I have missed anything which need to taken care or if any better approach for same.