首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SqlDataReader问题

SqlDataReader问题
EN

Stack Overflow用户
提问于 2015-08-09 20:02:54
回答 4查看 339关注 0票数 0

例外是:

当没有数据时,尝试无效。

但我不知道为什么?有人吗?ps: c=0最初

代码语言:javascript
复制
private void button2_Click(object sender, EventArgs e)
{
    using (SqlConnection connection = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=E:\C #\InsertDeleteUpdate-Login\InsertDeleteUpdate-Login\Database1.mdf;Integrated Security=True"))
    using (SqlCommand command = new SqlCommand("select * from info", connection))
    {
        connection.Open();

        using (SqlDataReader reader = command.ExecuteReader())
        {
            if(reader.HasRows)
            {
                if (reader["Id"].ToString() == textBox1.Text && reader["Password"].ToString() == textBox2.Text)
                {
                    reader.Read();
                    MessageBox.Show("Hello!");
                    c=1;
                }
            }

            if (c==0)
               MessageBox.Show("wrong id or password");
        }
    }
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-08-09 20:11:18

必须在访问reader.Read()的任何值成员之前调用它。如果读取成功与否,该函数将返回一个bool,最简单的解决方案是用read调用替换reader.HasRow调用。

代码语言:javascript
复制
    using (SqlConnection connection = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=E:\C #\InsertDeleteUpdate-Login\InsertDeleteUpdate-Login\Database1.mdf;Integrated Security=True"))
    using (SqlCommand command = new SqlCommand("select * from info", connection))
    {
        connection.Open();
        using (SqlDataReader reader = command.ExecuteReader())
        {
            if(reader.Read())
            {
                if (reader["Id"].ToString() == textBox1.Text && reader["Password"].ToString() == textBox2.Text)
                {
                    MessageBox.Show("Hello!");
                    c=1;
                }
            }
            if(c==0)
                MessageBox.Show("wrong id or password");
        }
    }

但是,您还可以做许多其他事情来改进代码,例如,现在您从info查询每一行,但只检查返回的第一行。通过使用参数,您可以将检查直接放在查询本身内。

代码语言:javascript
复制
    using (SqlConnection connection = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=E:\C #\InsertDeleteUpdate-Login\InsertDeleteUpdate-Login\Database1.mdf;Integrated Security=True"))
    using (SqlCommand command = new SqlCommand("select 1 from info where Id = @Id and Password = @Password", connection))
    {
        command.Parameters.Add("@Id", SqlDbType.NVarChar).Value = textBox1.Text;
        command.Parameters.Add("@Password", SqlDbType.NVarChar).Value = textBox2.Text;
        connection.Open();
        using (SqlDataReader reader = command.ExecuteReader())
        {
            if(reader.Read())
            {
                MessageBox.Show("Hello!");
            }
            else
            {
                MessageBox.Show("wrong id or password");
            }
        }
    }

您还可以做许多其他的改进,例如,您不应该将密码存储在数据库中的清空中,而是应该使用密码散列函数对其进行散列,但是我会让您自己查找。

UPDATE:正如史蒂夫在评论中指出的那样,更好的选择是放弃阅读器,转而使用ExecuteScalar()ExecuteScalar()返回第一行的值第一列,如果没有返回的行(如果数据库中的值是NULL,则返回DbNull.Value)。您所需要做的就是检查返回的值不等于null

代码语言:javascript
复制
    using (SqlConnection connection = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=E:\C #\InsertDeleteUpdate-Login\InsertDeleteUpdate-Login\Database1.mdf;Integrated Security=True"))
    using (SqlCommand command = new SqlCommand("select 1 from info where Id = @Id and Password = @Password", connection))
    {
        command.Parameters.Add("@Id", SqlDbType.NVarChar).Value = textBox1.Text;
        command.Parameters.Add("@Password", SqlDbType.NVarChar).Value = textBox2.Text;
        connection.Open();
        var result = command.ExecuteScalar();
        if(result != null)
        {
            MessageBox.Show("Hello!");
        }
        else
        {
            MessageBox.Show("wrong id or password");
        }
    }
票数 3
EN

Stack Overflow用户

发布于 2015-08-09 20:10:51

关于您的代码,首先要说明的是,您不应该将密码以明文形式存储在数据库中。正确的方法是使用某种密码学(本网站中有许多关于存储加密密码的例子)。

现在,您的问题是由于SqlDataReader最初没有定位在第一条记录之上。在尝试获取数据之前,您需要请求它读取记录。(此时调用HasRows是无用的,因为如果没有要读取的行,则Read方法将返回false )

代码语言:javascript
复制
        ....
        connection.Open();
        using (SqlDataReader reader = command.ExecuteReader())
        {
            if(reader.Read())
            {
                if (reader["Id"].ToString() == textBox1.Text && 
                    reader["Password"].ToString() == textBox2.Text)
                {
                    reader.Read();
                    MessageBox.Show("Hello!");
                    c=1;
                }
            }
            ....

他说,请看Scott Chamberlain的答案,找到更好的解决问题的方法。

票数 2
EN

Stack Overflow用户

发布于 2015-08-09 20:10:59

DataReader.Read返回一个布尔值,指示是否有更多的数据块要读取,因此,如果有超过1个结果,则可以这样做:

代码语言:javascript
复制
while (dr.Read()) {
  // read data for each record here
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31908330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档