调用OleDbDataReader.GetValue(0)抛出No data异常,明明存在数据
OleDbDataReader读取数据抛出InvalidOperationException的问题解决
你的代码执行到reader.GetValue(0)时抛出异常,核心问题和修正方案如下:
问题根源
当你通过cmd.ExecuteReader()获取OleDbDataReader实例后,它的指针默认处于第一条记录的前方,此时直接调用GetValue(0)读取数据,自然会触发No data exists for the row/column异常。
另外你的循环逻辑还存在两个隐患:
- 先读取值再调用
reader.Read(),会导致第一次循环读取的是无效位置的数据,后续循环也会出现错位 - 两次独立查询(先查count再查Id)之间,如果数据库数据发生增删,会出现count和实际返回行数不一致的情况,引发数组索引越界
修正后的代码
public static PersonalData[] GetAllPersonalInfo(OleDbCommand cmd) { cmd.CommandText = "SELECT Id From PersonalInfo"; List<PersonalData> personalList = new List<PersonalData>(); // 使用using自动释放阅读器资源,无需手动Close using (OleDbDataReader reader = cmd.ExecuteReader()) { // 先调用Read()移动指针到记录,再判断是否有数据 while (reader.Read()) { // 用强类型读取方法更安全,避免类型转换问题 int personId = reader.GetInt32(0); personalList.Add(GetOnePersonPersonalInfo(personId, cmd)); } } return personalList.ToArray(); }
关键优化点
- 修正读取顺序:通过
while(reader.Read())先将指针移动到有效记录,再执行读取操作,从根源避免无数据的异常 - 动态收集数据:用
List<PersonalData>代替固定长度数组,适配数据变化的场景,避免索引越界 - 自动资源管理:
using语句会自动关闭并释放OleDbDataReader资源,比手动调用Close()更可靠 - 强类型读取:使用
GetInt32这类强类型方法,减少装箱拆箱操作,同时避免GetValue返回object后的类型转换错误
内容的提问来源于stack exchange,提问作者amirmohammad firouzfar
相关产品推荐
相关产品推荐

