好的,我有一些非常简单的代码,我将在下面发布。本质上,我与数据库有一个连接,我希望将查询中的一个列子集映射到一个特定的类。问题是,这些值有可能为空。
我想知道如果在某一行抛出异常是否可能,我们是否可以从下一行恢复整个块。
因此,如果下面的代码要执行,并且第6行捕获一个错误。是否有一种优雅的方法来捕获异常并使代码在第7行继续运行,本质上就像第6行从未被执行过一样。
private static Column MapTableToColumn(OracleDataReader reader){
Column c = new Column();
c.ColumnName = Convert.ToString(reader["COLUMN_NAME"]);
c.DataType = Convert.ToString(reader["DATA_TYPE"]);
c.DataLength = Convert.ToInt32(reader["DATA_LENGTH"]);
c.DataPrecision = Convert.ToInt32(reader["Data_Precision"]);//<---Line 6
c.DataScale = Convert.ToInt32(reader["Data_scale"]);//<--- Line 7
c.AllowDBNull = Convert.ToBoolean(reader["ALLOW_DB_NULL"]);
c.IsReadOnly = Convert.ToBoolean(reader["IS_READ_ONLY"]);
c.IsLong = Convert.ToBoolean(reader["IS_LONG"]);
c.IsKey = Convert.ToBoolean(reader["IS_KEY"]);
c.KeyType = Convert.ToString(reader["KEY_TYPE"]);
c.IsUnique = Convert.ToBoolean(reader["IS_UNIQUE"]);
c.Description = Convert.ToString(reader["DESCRIPTION"]);
return c;
}值得注意的是,我并不是在要求最佳实践,它不是我打算在实际代码中使用的东西(除非它绝对是天才)。我只想知道这是否有可能,如果可能的话,我们会怎么做。
我的研究
我的大部分研究都是主动的,而不是被动的。我试图知道在读取给定字段之前是否可以将其为null。如果是,那么我将进行检查以确定该字段是否为null,然后将其设置为默认值。它基本上避免了错误发生的可能性,我认为这是一个很好的解决方案。我只想尝试这样做,因为我知道当抛出异常时,最内部的异常包含抛出它的行号。基于此,如果您将异常放入类中,抛出异常,则假设您应该能够使用反射,以便从其最后一点继续运行。我只是不知道你会怎么做。我还考虑过在每一条线周围放置“尝试捕捉”的可能性,我认为这是非常有效的;然而,我认为它会非常丑陋。
发布于 2013-09-03 14:44:01
不,您所要求的在C#中是不可能的。
相反,正确的解决这个问题的方法是使用更好的解析方法,这些方法一开始不会抛出异常。如果输入值可以为空,则使用可以接受空值的解析方法。
您可能需要做的第一件事是对int/bool字段使用可空类型,以便可以支持空值。接下来,您需要创建自己的方法来解析您的ints/bools。如果输入为null,则返回null,如果不是,则使用int.TryParse、bool.TryParse (如果输入是正确的类型,则使用as ),只需强制转换为object)。
然后,通过使用这些方法,而不是Convert,您将不会首先抛出异常(即使它可以工作,也不应该在这里这样做,因为异常是针对异常情况的,而不是预期的控制流)。
发布于 2013-09-03 14:50:58
如果是预期的例外,那么它也不是例外。永远不会捕捉空引用异常。空引用异常是一个bug。相反,编写代码以避免错误。
您可以轻松地编写用于测试null的助手方法,也可以使用像Int32.TryParse这样的方法来处理格式错误的字符串。
发布于 2013-09-03 14:46:16
检查IsDBNull
SqlDataReader.IsDBNull法
并且Reader对每个SQL数据类型都有方法。
例如
SqlDataReader.GetSqlBoolean
如果数据在string (char,nchar)中,那么首先检查null,然后检查TryParse
例如
DateTime.TryParse
序号位置更快
这是一个可为空的Int16的示例
Int16? ID;
ID = rdr.IsDBNull(4) ? (Int16?)null : rdr.GetInt16(4);如果您想要缺省值
Int16 ID;
ID = rdr.IsDBNull(4) ? 0 : rdr.GetInt16(4);https://stackoverflow.com/questions/18595060
复制相似问题