另一个 "Invalid attempt to read when no data is present." 错误
Yet another "Invalid attempt to read when no data is present." error
我正在尝试从我的数据库中的视图中提取一个字段。我确定有这个实例的数据,我正确设置了 SQLDataReader(我相信),调试器验证我在 DataReader 中有行,但是当我尝试读取时出现错误。
代码如下:
public string[] getReasons(string Accession) {
string[] reasonList = new string[0];
SqlParameter accNumber = new SqlParameter();
accNumber.SqlDbType = System.Data.SqlDbType.VarChar;
accNumber.ParameterName = "@Accession";
accNumber.Value = Accession;
string selectText = "select reason from pendingList where accession = @Accession";
SqlCommand selectStmt = new SqlCommand(selectText,toPending);
selectStmt.Parameters.Add(accNumber);
if (selectStmt.Connection.State == System.Data.ConnectionState.Closed) {
selectStmt.Connection.Open();
}
SqlDataReader pendList = selectStmt.ExecuteReader();
while (pendList.Read()) {
reasonList[reasonList.Length] = pendList["reason"].toString();
}
pendList.Close();
return reasonList;
}
我调用 getReasons('RAM4658980')。我已验证以下 SQL 查询
select reason
from pendingList
where accession = 'RAM4658980'
returns 正好一行。 pendList
变量如下所示:
我不确定为什么会收到 "Enumeration yielded no results";在 reasonList[reasonList.Length] = pendList["reason"].toString();
这一步,我自然会得到 "Invalid attempt to read ..." 错误。我错过了什么?
你不应该使用调试器 "verify that you have rows in a reader"。虽然 SqlDataReader
(和一般的 DbDataReader
)实现了 IEnumerable
,但它们很特殊,因为 reader 是向前只读数据库游标的托管等价物,因此在迭代时,它确实消耗 底层游标,或者简单地说,它可以只迭代一次。如果您使用调试器,您实际上是在发射一颗子弹。
改为验证缓冲结果(reasonList
在您的情况下)。
更新: 事实上,除了上述之外,您的代码中还有一个错误 - reasonList
数组。为了更正它,使用类似这样的东西(注意 new List<string>
、reasonList.Add
和 reasonList.ToArray
):
public string[] getReasons(string Accession) {
var reasonList = new List<string>();
SqlParameter accNumber = new SqlParameter();
accNumber.SqlDbType = System.Data.SqlDbType.VarChar;
accNumber.ParameterName = "@Accession";
accNumber.Value = Accession;
string selectText = "select reason from pendingList where accession = @Accession";
SqlCommand selectStmt = new SqlCommand(selectText,toPending);
selectStmt.Parameters.Add(accNumber);
if (selectStmt.Connection.State == System.Data.ConnectionState.Closed) {
selectStmt.Connection.Open();
}
SqlDataReader pendList = selectStmt.ExecuteReader();
while (pendList.Read()) {
reasonList.Add(pendList["reason"].toString());
}
pendList.Close();
return reasonList.ToArray();
}
我正在尝试从我的数据库中的视图中提取一个字段。我确定有这个实例的数据,我正确设置了 SQLDataReader(我相信),调试器验证我在 DataReader 中有行,但是当我尝试读取时出现错误。
代码如下:
public string[] getReasons(string Accession) {
string[] reasonList = new string[0];
SqlParameter accNumber = new SqlParameter();
accNumber.SqlDbType = System.Data.SqlDbType.VarChar;
accNumber.ParameterName = "@Accession";
accNumber.Value = Accession;
string selectText = "select reason from pendingList where accession = @Accession";
SqlCommand selectStmt = new SqlCommand(selectText,toPending);
selectStmt.Parameters.Add(accNumber);
if (selectStmt.Connection.State == System.Data.ConnectionState.Closed) {
selectStmt.Connection.Open();
}
SqlDataReader pendList = selectStmt.ExecuteReader();
while (pendList.Read()) {
reasonList[reasonList.Length] = pendList["reason"].toString();
}
pendList.Close();
return reasonList;
}
我调用 getReasons('RAM4658980')。我已验证以下 SQL 查询
select reason
from pendingList
where accession = 'RAM4658980'
returns 正好一行。 pendList
变量如下所示:
我不确定为什么会收到 "Enumeration yielded no results";在 reasonList[reasonList.Length] = pendList["reason"].toString();
这一步,我自然会得到 "Invalid attempt to read ..." 错误。我错过了什么?
你不应该使用调试器 "verify that you have rows in a reader"。虽然 SqlDataReader
(和一般的 DbDataReader
)实现了 IEnumerable
,但它们很特殊,因为 reader 是向前只读数据库游标的托管等价物,因此在迭代时,它确实消耗 底层游标,或者简单地说,它可以只迭代一次。如果您使用调试器,您实际上是在发射一颗子弹。
改为验证缓冲结果(reasonList
在您的情况下)。
更新: 事实上,除了上述之外,您的代码中还有一个错误 - reasonList
数组。为了更正它,使用类似这样的东西(注意 new List<string>
、reasonList.Add
和 reasonList.ToArray
):
public string[] getReasons(string Accession) {
var reasonList = new List<string>();
SqlParameter accNumber = new SqlParameter();
accNumber.SqlDbType = System.Data.SqlDbType.VarChar;
accNumber.ParameterName = "@Accession";
accNumber.Value = Accession;
string selectText = "select reason from pendingList where accession = @Accession";
SqlCommand selectStmt = new SqlCommand(selectText,toPending);
selectStmt.Parameters.Add(accNumber);
if (selectStmt.Connection.State == System.Data.ConnectionState.Closed) {
selectStmt.Connection.Open();
}
SqlDataReader pendList = selectStmt.ExecuteReader();
while (pendList.Read()) {
reasonList.Add(pendList["reason"].toString());
}
pendList.Close();
return reasonList.ToArray();
}