在 C# 应用程序中找不到 InvalidCastException
Cannot find InvalidCastException in C# Application
我在 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);
}
}
}
同样,我得到的唯一错误是 "System.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 和 App)中使用相同的类型,以避免转换异常 --> 从 varchar 转换为 int 是不一样的,从int 到 int(当然它作为一个对象出现,但肯定它有一个类型期望值),当使用相同的类型时,你减少了很多验证逻辑。
如果你的table的字段接受空值,考虑使用转换策略(就像我给你的方法)在空值时分配一个有效值。
尽量避免在DataAccess方法中写太多"logic",保持简单,可以使用DTO或业务class来存储所有值你从数据库中得到,然后在业务层使用it/modify/create一个逻辑。
希望对你有帮助
我在 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);
}
}
}
同样,我得到的唯一错误是 "System.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 和 App)中使用相同的类型,以避免转换异常 --> 从 varchar 转换为 int 是不一样的,从int 到 int(当然它作为一个对象出现,但肯定它有一个类型期望值),当使用相同的类型时,你减少了很多验证逻辑。
如果你的table的字段接受空值,考虑使用转换策略(就像我给你的方法)在空值时分配一个有效值。
尽量避免在DataAccess方法中写太多"logic",保持简单,可以使用DTO或业务class来存储所有值你从数据库中得到,然后在业务层使用it/modify/create一个逻辑。
希望对你有帮助