0

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.

4
  • 2
    What line is the exception occurring at? You have 2 (ulong) casts, this may be it Commented Jun 8, 2015 at 15:27
  • 1
    Yeah, casting directly from a DataReader item won't work. Just to test, try replacing (i.e.) start = (ulong)rdr["startTime"]; with start = ulong.Parse(rdr["startTime"].ToString()) Commented Jun 8, 2015 at 15:35
  • @DenisYarkovoy Great question, but as I explained, it won't tell me lines. It only says that it's happening, nothing more. Commented Jun 8, 2015 at 15:38
  • @helrich please post as answer so I can mark it correct. It worked. Commented Jun 8, 2015 at 15:40

2 Answers 2

1

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").

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.