在c#应用程序中找不到InvalidCastException
本文关键字:找不到 InvalidCastException 应用程序 | 更新日期: 2023-09-27 17:54:28
我在Visual Studio中遇到了一个奇怪的错误,当然这个伟大的软件无法告诉我错误在哪里,只是我遇到了一个错误。我想我能做的最好的就是粘贴我的代码。
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);
}
}
}
再次,我得到的唯一错误是"系统。InvalidCastException"发生在.exe.
对象的直接强制转换仅在该对象继承了要强制转换到的类型时才有效(无论如何,在这一行的某个地方)。
从DataReader
获得所需类型的一个简单方法是调用
[type].Parse(reader[index].ToString())
其中[type]
是您想要强制转换的对象,即
ulong.Parse(rdr["startTime"].ToString())
DataReader
对象通常有.GetInt32(int)
、.GetDecimal(int)
等,只需要传入要解析的列的索引。如果只有列的名称,可以使用Reader.GetOrdinal("yourColumnName")
。
我建议您使用一个额外的方法来分隔这类错误。例如,考虑以下代码:
protected T getDataValue<T>(object value)
{
if (value != null && DBNull.Value != value)
return (T)value;
else
return default(T);
}
然后在数据读取器迭代中为每个检索到的值调用它,这将帮助您在调试期间检测哪个字段产生异常。例子:
start = getDataValue<ulong>(rdr["startTime"]);
end = getDataValue<ulong>(rdr["endTime"]);
简而言之,在处理数据访问时,我通常遵循以下指导原则来避免异常:
如果你可以访问数据库,在从ADO执行查询之前使用db客户端检查你的数据,这可以执行相同的查询。
考虑在两层(DB和App)中使用相同的类型,为了避免强制转换异常->从varchar转换为int是不一样的,从int转换为int(当然它是作为一个对象,但肯定它有一个类型期望值),当使用相同的类型时,你减少了很多验证逻辑。
如果您的表字段接受null,请考虑使用转换策略(如我给您的方法)在null时分配一个有效值。
尽量避免在DataAccess方法中编写太多的"逻辑",只需保持简单,您可以使用DTO或业务类来存储从db中获得的所有值,然后在业务层使用它/修改/创建逻辑。
希望有所帮助