Cannot find InvalidCastException in C# Application

425 views Asked by At

I'm getting a strange error in Visual Studio, and of course this great software is unable to tell me where the error is, just that I'm getting an error. I guess the best I can do is paste my code.

using (SQLiteCommand cmd = new SQLiteCommand(query, con))
{
    using (SQLiteDataReader rdr = cmd.ExecuteReader())
    {
        while (rdr.Read())
        {
            //Console.WriteLine("{0} ", rdr["logLnNum"]);
            ulong start, end, delta = 0;
            string contentStr;
            string contentMarkup;
            String group;

            start = (ulong)rdr["startTime"];
            end = (ulong)rdr["endTime"];
            convertTimes(start, end, 2728232, delta);

            contentStr = String.Format("{0}, {1}, {2}, {3}, {4} (ms)", 
                rdr["offsetOfData"], rdr["amountOfData"], rdr["filename"], 
                rdr["logLnNum"], (delta * .001));
            contentMarkup = "<div title=\"" + contentStr + "\">" + contentStr + "</div>";

            group = String.Format("{0:X}", rdr["threadId"]);
            group = group + ", " + rdr["threadName"];

            TimelineData inputData = new TimelineData(contentMarkup, end, group, start);
            Console.WriteLine("Data processed");
            dataSet.Add(inputData);
        }
    }
}

Again, the only error I get is "System.InvalidCastException" occurred in .exe.

2

There are 2 answers

0
helrich On BEST ANSWER

Direct casting from an object only works when that object inherits from the type you're casting to (somewhere along the line, anyways).

A simple way to get the type you need out of a DataReader is to call

[type].Parse(reader[index].ToString())

where [type] is what you want to cast to, i.e.

ulong.Parse(rdr["startTime"].ToString())

The DataReader objects typically have a .GetInt32(int), .GetDecimal(int), etc. that simply requires you to pass in the index of the column to parse. If you only have the name of the column, you can use Reader.GetOrdinal("yourColumnName").

0
cloud120 On

I would like to recommend you using an extra method to delimit this kind of errors. For instance, consider this code:

protected T getDataValue<T>(object value)
{
        if (value != null && DBNull.Value != value)
            return (T)value;
        else
            return default(T);
}

Then call it inside your datareader iteration for each value retrieved, this will help you during debugging to detect which field is producing the exception. Example:

start = getDataValue<ulong>(rdr["startTime"]);
end = getDataValue<ulong>(rdr["endTime"]);

In a nutshell, I usually follow these guidelines when working with data access to avoid exceptions:

  • If you have access to database, check your data using a db client before executing queries from ADO, this can be done executing the same query.

  • Consider using the same types in both layers (DB and App), in order to avoid cast exceptions --> it's not the same to convert from varchar to int, that making a simple cast from int to int (of course it comes as an object but for sure it has a type expected value), you reduce a lot of validation logic when using the same types.

  • If your table's fields accept nulls, consider using a strategy of conversion (like the method I gave you) to assign a valid value when null.

  • Try to avoid writing too much "logic" in DataAccess methods, just keep it simple, you can use a DTO or a business class in order to store all the values you've got from db, then use it/modify/create a logic in the business layer.

Hope it helps