我有一个从 C# 中的记录集转换的工作代码,但我也遇到了其他方法,我一直在研究它们的用途。这是测试代码:
`using (DataTableReader reader = new DataTableReader(ds2.Tables[0]))
{
while (reader.Read())
{
//sample of working code. The values are on the far right.
string val1 = reader[0] is DBNull ? default(string) : reader[0].ToString(); //value = "test"
int val2 = reader[2] is DBNull ? default(int) : Convert.ToInt32(reader[2].ToString()); //value = 23
bool val3 = reader[26] is DBNull ? default(bool) : reader[26].ToString() == "1" ? true : false; //value = true
DateTime val4 = reader[16] is DBNull ? default(DateTime) : Convert.ToDateTime(reader[16].ToString()); //value= 10/6/2013 6:31:33 AM
//the first approach
string val5 = reader[0] as string;
int? val6 = reader[2] as int? ?? default(int);
bool? val7 = reader[26] as bool? ?? default(bool);
DateTime? val8 = reader[16] as DateTime? ?? default(DateTime);
//the second approach
string val9 = reader[0] is DBNull ? default(string) : reader.GetString(0);
int val10 = reader[2] is DBNull ? default(int) : reader.GetInt32(2); ;
bool val11 = reader[26] is DBNull ? default(bool) : reader.GetBoolean(26);
DateTime val12 = reader[16] is DBNull ? default(DateTime) : reader.GetDateTime(16);
//the third approach
var val13 = reader[0] is DBNull ? default(string) : (string)reader[0];
int val14 = reader[2] is DBNull ? default(int) : (int)reader[2]; ;
bool val15 = reader[26] is DBNull ? default(bool) : (bool)reader[26];
DateTime val16 = reader[16] is DBNull ? default(DateTime) : (DateTime)reader[16];
//the 4th approach
int val17 = reader[2] is DBNull ? default(int) : (int) Int32.Parse(reader[2].ToString());
bool val18 = reader[26] is DBNull ? default(bool) : (bool) Boolean.Parse( reader[26].ToString()=="1"? "true" : "false");
DateTime val19 = reader[16] is DBNull ? default(DateTime) : (DateTime) DateTime.Parse(reader[16].ToString());
}
}`
此 SO Q&A显示了第一种和第二种方法的示例。我从此SO Q&A中获取的第三种方法。第四种方法就是从这里开始的。
在第一种方法中, as 运算符与 ?? 默认值的运算符,因为 as 运算符处理强制转换和检查 DBNull,评论者指出,如果出现错误,这将静默失败。使用此代码,我得到了字符串的空值和其余的默认值,这表明“as”运算符以某种方式失败了。
第二种方法使用读者的 Getxxxx() 方法。但这会引发异常“无法将'System.Data.SqlTypes.SqlString'类型的对象转换为'System.String'类型。” 对于字符串和“指定的强制转换无效”。为其他人。第三种方法使用强制转换并生成与第二种方法相同的异常。
第四种方法有效,首先将数据转换为字符串,解析字符串,最后转换为预期的类型。我使用TryParse()和Convert.ChangeType()遇到了更多,但它们更冗长。
我的问题是,那些其他方法似乎对其他人有效(他们是答案并被赞成),但当我使用它们时为什么不呢?我在这里做错了什么?如果可以使它们起作用,哪一种是最有效的方法?
编辑: 正如@usr 所建议的,我应该使用一些辅助方法。这是我将用于工作代码的辅助方法,以及示例用法:
public static T GetColumnValue<T>(this DataTableReader reader, string columnName)
{
T result = default(T);
int index = reader.GetOrdinal(columnName);
if (!reader.IsDBNull(index))
{
result = (T)Convert.ChangeType(reader[index].ToString(), typeof(T));
}
return result;
}
//used as
string val1 = reader.GetColumnValue<string>("Column1");
int val2 = reader.GetColumnValue<int>("Column2");
bool val3 = reader.GetColumnValue<bool>("Column3");
DateTime val4 = reader.GetColumnValue<DateTime>("Column4");
当然,这不适用于其他方法。我仍然很好奇为什么其他方法不起作用。谢谢。