1

我有一个SqlDataReader从中提取数据的。我正在尝试根据来自阅读器的数据向用户显示不同的消息。当我的 if 语句返回 true 时,当 if 语句返回 false 时,数据正确显示,我得到一个冗长的错误:

System.InvalidOperationException:不存在数据时尝试读取无效。 在 System.Data.SqlClient.SqlDataReader.TryReadColumn (Int32 i, Boolean setTimeout, Boolean allowPartiallyReadColumn) 在 System.Data.SqlClient
的 System.Data.SqlClient.SqlDataReader.CheckDataIsReady(Int32 columnIndex, 布尔 allowPartiallyReadColumn, 布尔 permitAsync, String methodName) 。
SqlDataReader.GetValueInternal(Int32 i)
在 System.Data.SqlClient.SqlDataReader.GetValue(Int32 i)
在 System.Data.SqlClient.SqlDataReader.get_Item(String name)

这是我的代码:

protected void Page_Load(object sender, EventArgs e)
{
    MembershipUser user = Membership.GetUser();
    string key = user.ProviderUserKey.ToString();

    SqlConnection con = new SqlConnection(connectionString);
    SqlCommand cmd = new SqlCommand("usp_GetDetails", con);
    cmd.CommandType = CommandType.StoredProcedure;

    cmd.Parameters.AddWithValue("@UserKey", key);

    SqlDataReader reader;
    try
    {
        con.Open();
        reader = cmd.ExecuteReader();

        reader.Read();

        getBidNumber = reader["SelectedBid"].ToString();
        getCompanyName = reader["CompanyName"].ToString();
        getUserKey = reader["MembershipUserKey"].ToString();
        getMerchantKey = reader["MerchantKey"].ToString();
        getMerchantName = reader["MerchantName"].ToString();

        this.DataBind();

        if (getBidNumber != null)
        {
            lblBidSelected.Text = "Congratulations you have selected #" + getBidNumber + " from " + getCompanyName + ". Click here to review you bid details.";
        }

        else
        {
            lblNoBidSelected.Text = "You have not selected a processor. Please <a href='bids-visit.aspx?mkey=" + getMerchantKey + "'>click here</a> to review your bids.";
        }


    }
    catch (Exception err)
    {
        lblError.Text = "There was an error " + err;
    }
    finally
    {
        con.Close();
    }

}
4

5 回答 5

2

我建议使用 更具可读性HasRows的属性SqlDataReader,如下所示:

if (reader.HasRows) 
{
    while (reader.Read()) 
    {
        // Do your reading logic here
        getBidNumber = reader["SelectedBid"].ToString();
        getCompanyName = reader["CompanyName"].ToString();
        getUserKey = reader["MembershipUserKey"].ToString();
        getMerchantKey = reader["MerchantKey"].ToString();
        getMerchantName = reader["MerchantName"].ToString();
    }
}

注意:这使得您的阅读逻辑为什么或为什么不处理任何数据非常明显。

更新:

if-else将您的逻辑更改为:

if (!String.IsNullOrEmpty(getBidNumber))
{
    lblBidSelected.Text = "Congratulations you have selected #" + getBidNumber + " from " + getCompanyName + ". Click here to review you bid details.";
}
else
{
    lblNoBidSelected.Text = "You have not selected a processor. Please <a href='bids-visit.aspx?mkey=" + getMerchantKey + "'>click here</a> to review your bids.";
}

注意:Astring会初始化为空字符串,不为null,ToString()也不会返回null;因此使用该IsNullOrEmpty()方法检查值更符合您的方法。

于 2013-10-17T13:54:03.197 回答
0

既然你在里面else,这意味着:

reader==null -> getMerchantKey = reader["MerchantKey"].ToString()==null

-> 你得到你的错误

于 2013-10-17T13:47:20.980 回答
0

问题不在else区块内部。早先抛出异常,在这一行:

getBidNumber = reader["SelectedBid"].ToString();

它在那里抛出的原因是因为调用reader.Read()没有产生任何结果。似乎问题出在else上,因为如果调用reader.Read()成功,则if条件将始终测试为true. 你真正想要的是这样的代码:

if (reader.Read())
{
    getBidNumber = reader["SelectedBid"].ToString();
    getCompanyName = reader["CompanyName"].ToString();

    lblBidSelected.Text = "Congratulations you have selected # ... "
}
else
{
    //You'll need to change your error message, because the merchant key is unknown
    blNoBidSelected.Text = "You have not selected a processor. ... "
}
于 2013-10-17T13:50:30.300 回答
0

您在到达 if 语句之前收到此错误,可能是因为您的查询没有返回任何行。在继续之前检查 reader.Read() 返回值。

于 2013-10-17T13:51:21.390 回答
0

首先像这样初始化

string getBidNumber =null;

以及何时进行字符串转换检查 reader["SelectedBid"] 是否为空。

if(reader["SelectedBid"] !=null)
{
getBidNumber = reader["SelectedBid"].ToString();
}

其余代码都一样。祝你好运

于 2013-10-17T14:16:12.810 回答