1

关于登录系统,我的代码有问题。当我在我的数据库中添加 1 个用户名和密码时,它可以正常工作。但是当我在数据库中添加另外 1 个用户名和密码时,我的 else 语句会弹出两次。当 3 个用户名和密码时,我的 else 语句将弹出三次。等等等等..这是我的代码..如果你有比我更好的代码,请出示。

SqlConnection con = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\Users\\JEDMARC\\Desktop\\VS v1.0.0\\Voting System v1.0.0\\Voting System v1.0.0.mdf;Integrated Security=True;User Instance=True");
    SoundPlayer t = new SoundPlayer(@"C:\Users\JEDMARC\Documents\welcome.wav");

    private void btnEnter_Click(object sender, EventArgs e)
    {
 if (cmbToE.Text == "HomeRoom Election" && comboBox1.Text == "English")
        {
            con.Open();

            SqlCommand da = new SqlCommand("SELECT * FROM RegistrationTable", con);

            SqlDataReader reader = null;
            reader = da.ExecuteReader();
            while (reader.Read())
            {
                if (tbUsername.Text == (reader["Username"].ToString()) && tbPassword.Text == (reader["Password"].ToString()))
                {
                    MessageBox.Show("*Choose your best candidate. Use a Combobox.\n\n*After choosing, click Submit button to pass your vote!\n\n                           VOTE WISELY!", "How to vote?", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                    UserHRForm x = new UserHRForm();
                    x.Show();
                    t.Play();
                    this.Close();
                }
                else
                {
                    SystemSounds.Hand.Play();
                    MessageBox.Show("Access Denied! Account doesn't exist!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);                        
                }
            }
        }
}
4

2 回答 2

2

您的 while 循环会检查数据库中的每个用户,因此它会击中正确的用户一次,然后击中错误的用户两次。要按照您现在编写代码的方式执行此操作,您必须在while循环中使用一个标志来跟踪您是否找到了正确的用户/密码组合。就像是:

        bool foundUser = false;

        while (reader.Read())
        {
            if (tbUsername.Text == (reader["Username"].ToString()) && tbPassword.Text == (reader["Password"].ToString()))
            {
                foundUser = true;
                break;
            }
        }


        if (foundUser) {
                MessageBox.Show("*Choose your best candidate. Use a Combobox.\n\n*After choosing, click Submit button to pass your vote!\n\n                           VOTE WISELY!", "How to vote?", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                UserHRForm x = new UserHRForm();
                x.Show();
                t.Play();
                this.Close();
            }
            else
            {
                SystemSounds.Hand.Play();
                MessageBox.Show("Access Denied! Account doesn't exist!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);                        
            }

但这是对代码的非常低效的使用。相反,让 SQL 为您处理过滤器。这就是它的设计目的。

        con.Open();

        SqlCommand da = new SqlCommand("SELECT * FROM RegistrationTable WHERE Username=@Username AND Password=@Password", con);
        da.Parameters.Add("@Username ", SqlDbType.Varchar);
        da.Parameters["@Username "].Value = tbUsername.Text;
        da.Parameters.Add("@Password", SqlDbType.Varchar);
        da.Parameters["@Password"].Value = tbPassword.Text;

        SqlDataReader reader = null;
        reader = da.ExecuteReader();

            if (da.HasRows)
            {
                MessageBox.Show("*Choose your best candidate. Use a Combobox.\n\n*After choosing, click Submit button to pass your vote!\n\n                           VOTE WISELY!", "How to vote?", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                UserHRForm x = new UserHRForm();
                x.Show();
                t.Play();
                this.Close();
            }
            else
            {
                SystemSounds.Hand.Play();
                MessageBox.Show("Access Denied! Account doesn't exist!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);                        
            }
        }
于 2012-10-28T07:10:26.693 回答
2

要解决直接问题,您要使用break关键字退出while循环。

从长远来看,您应该考虑过滤掉 SQL 调用中的用户:

SqlCommand da = new SqlCommand(
    "SELECT * FROM RegistrationTable" + 
    "Where Username = @Username and Password = @Password", con);

da.Parameters.Add("@Username ", SqlDbType.Varchar);
da.Parameters["@Username "].Value = tbUsername.Text;
da.Parameters.Add("@Password", SqlDbType.Varchar);
da.Parameters["@Password"].Value = tbPassword.Text;

这将确保数据读取器返回一个或零个元素(除非有人可以复制他们的登录)。您正在做的是返回整个表,并遍历每个结果,SQL 可以比您的 C# 代码更有效地执行这项工作。阅读“永远不要在代码中做可以让 SQL 服务器为您做好的事情”——这是一个糟糕设计的秘诀吗?.

于 2012-10-28T07:04:26.063 回答