1

ログインシステムに関して、ここのコードに問題があります。データベースに 1 つのユーザー名とパスワードを追加すると、正しく機能します。しかし、データベースに別の 1 つのユーザー名とパスワードを追加すると、else ステートメントが 2 回ポップアップします。3 つのユーザー名とパスワードを指定すると、else ステートメントが 3 回表示されます。などなど..これが私のコードです..私のコードよりも優れたコードがある場合は、それを示してください。

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 ループは DB 内のすべてのユーザーをチェックするため、正しいユーザーに 1 回ヒットし、間違ったユーザーに 2 回ヒットします。コードが現在書かれている方法でそれを行うには、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;

これにより、データ リーダーが 1 つまたは 0 の要素を返すことが保証されます (誰かがログインを複製できない場合)。テーブル全体を返し、各結果をループすることで、SQL はこのジョブを C# コードよりもはるかに効率的に実行できます。「SQL サーバーにうまくやってもらうことができることをコードで行うな」を読んでください - これは悪い設計のレシピですか? .

于 2012-10-28T07:04:26.063 に答える