还有一个“没有数据时无效的读取尝试”。错误

时间:2015-11-02 18:57:22

标签: c# sql-server visual-studio sql-server-2005

我正在尝试从数据库中的视图中提取一个字段。我确定这个实例有数据,我正确设置了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'

只返回一行。 pendList变量如下所示:

pendList variable contents

我不确定为什么会得到“枚举没有结果”;在reasonList[reasonList.Length] = pendList["reason"].toString();步骤,我自然得到“无效尝试读取...”错误。我错过了什么?

1 个答案:

答案 0 :(得分:1)

您不应该使用调试器来确认您在阅读器中有行"。虽然SqlDataReader(和DbDataReader一般)实现IEnumerable,但它们是特殊的,因为reader是仅向前只读数据库游标的托管等效项,因此在迭代时,它确实消耗底层光标,或者简单来说,它可以迭代一次。如果你使用调试器,你就可以有效地射击你的单个子弹。

改为验证缓冲结果(在您的情况下为reasonList)。

更新:实际上除了上述内容之外,您的代码中还有一个错误 - reasonList数组。要更正它,请使用以下内容(注意new List<string>reasonList.AddreasonList.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();
}