求通用DataRow列读取函数:解决数值转字符串类型转换异常
问题分析与解决方案
核心问题
你遇到的是强制类型转换和类型转换操作的本质区别:原代码里的(T)dataRow[index]是强制转换,只有当对象本身就是目标类型T时才有效。比如数据库列是varchar存的"1"(string类型)转string没问题,但如果列是int存的1(Int32类型),直接强制转string就会报错——因为Int32对象无法直接被cast成string类型。
修复后的通用工具方法
修改Utils.GetDbValue方法,改用Convert.ChangeType实现跨类型转换,同时处理空值和列不存在的场景:
public static class Utils { public static T GetDbValue<T>(DataRow dataRow, string columnName) { int index = dataRow.Table.Columns.IndexOf(columnName); // 处理列不存在或值为空的情况 if (index < 0 || index >= dataRow.ItemArray.Length || dataRow.IsNull(columnName)) { return default(T); } var value = dataRow[index]; try { if (value == DBNull.Value) return default(T); // 自动处理跨类型转换(如Int32转string、string转Int32、DateTime转string等) return (T)Convert.ChangeType(value, typeof(T)); } catch (InvalidCastException) { // 转换失败时返回默认值,也可根据业务需求抛出异常 return default(T); } } }
扩展优化(可选)
如果需要更精细化的控制,比如字符串类型空值返回空字符串而非null,可以在方法中加入特定类型的逻辑:
// 在Convert.ChangeType之前添加 if (typeof(T) == typeof(string)) { return (T)(object)(value?.ToString() ?? string.Empty); }
使用示例
在MyObject构造函数中直接调用即可,不再区分列的原始类型:
public MyObject(DataRow dr) { // 不管comments列是Int32还是string,都能正常转为string _comments = Utils.GetDbValue<string>(dr, "comments"); // 其他类型也兼容 _age = Utils.GetDbValue<int>(dr, "age"); _createTime = Utils.GetDbValue<DateTime>(dr, "create_time"); }
内容的提问来源于stack exchange,提问作者BillSig
相关产品推荐
相关产品推荐

