例外是:
当没有数据时,尝试无效。
但我不知道为什么?有人吗?ps: c=0最初
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");
}
}
}发布于 2015-08-09 20:11:18
必须在访问reader.Read()的任何值成员之前调用它。如果读取成功与否,该函数将返回一个bool,最简单的解决方案是用read调用替换reader.HasRow调用。
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查询每一行,但只检查返回的第一行。通过使用参数,您可以将检查直接放在查询本身内。
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。
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");
}
}发布于 2015-08-09 20:10:51
关于您的代码,首先要说明的是,您不应该将密码以明文形式存储在数据库中。正确的方法是使用某种密码学(本网站中有许多关于存储加密密码的例子)。
现在,您的问题是由于SqlDataReader最初没有定位在第一条记录之上。在尝试获取数据之前,您需要请求它读取记录。(此时调用HasRows是无用的,因为如果没有要读取的行,则Read方法将返回false )
....
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的答案,找到更好的解决问题的方法。
发布于 2015-08-09 20:10:59
DataReader.Read返回一个布尔值,指示是否有更多的数据块要读取,因此,如果有超过1个结果,则可以这样做:
while (dr.Read()) {
// read data for each record here
}https://stackoverflow.com/questions/31908330
复制相似问题