OleDbDataReader 读取 command.ExecuteReader();

OleDbDataReader reading command.ExecuteReader();

我尝试用访问数据库编写一个简单的登录表单。 在我按下登录按钮后,它的 return 进行编码并标记为:

OleDbDataReader reader= command.ExecuteReader();

连接成功但是当我按下登录时 return。

mdb 名称: users1.mdb table 名称: 数据数据

图片: https://imgur.com/a/gl2Xfga

我的代码有什么问题?

</p> <pre>using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Data.OleDb; namespace CDHW { public partial class Form1 : Form { private OleDbConnection connection = new OleDbConnection(); public Form1() { InitializeComponent(); connection.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source = C:\Users\RBA\Desktop3\users1.mdb; Persist Security Info=False;"; } private void Form1_Load(object sender, EventArgs e) { try { connection.Open(); checkConnection.Text = "Connection Successful"; connection.Close(); } catch (Exception ex) { MessageBox.Show("Error " + ex); } } private void groupBox1_Enter(object sender, EventArgs e) { } private void btn_Login_Click(object sender, EventArgs e) { connection.Open(); OleDbCommand command = new OleDbCommand(); command.Connection = connection; command.CommandText = "select * from DataData where User='" + text_Username.Text + "' and Password='" + text_Password.Text + "'"; OleDbDataReader reader= command.ExecuteReader(); int count = 0; while (reader.Read()) { count = count + 1; //count++; // } if (count == 1) { MessageBox.Show("Wellcome to G Tool"); } if (count == 1) { MessageBox.Show("Password is duplicated"); } else { MessageBox.Show("User Name or Password is incorrect"); } connection.Close(); } } }

注意:请参阅重新转义 UserPassword 的注释。

这里首先要考虑的是:参数。现在,如果 username/password 包含一系列字符,就会发生非常糟糕的事情;所以:

command.CommandText = "select * from DataData where [User]=@cn and [Password]=@pw";
command.Parameters.Add(new OleDbParameter("@cn", text_Username.Text));
command.Parameters.Add(new OleDbParameter("@pw", text_Password.Text));

下一个问题是纯文本密码,但那是一个很大的领域——只是...永远不要将密码存储为文本...永远。

现在,我假设上述没有解决它;如果是这样,您需要检查 UserPassword 是如何在数据库中定义的。错误消息表明其中一个不是很像文本。

此代码中存在 很多 using 等问题,可能导致与 "open reader" 等相关的奇怪错误;如果可能的话,我强烈推荐一个像 Dapper 这样的工具,它可以使正确编写此类代码变得容易得多。例如:

var userIds = connection.Query<string>(
    "select [User] from DataData where [User]=@cn and [Password]=@pw",
    new { cn = text_Username.Text, pw = text_Password.Text }).AsList();
switch(userIds.Count) {
    case 0: // TODO: doesn't exist
    case 1: // TODO: perfect
        break;
    default: // TODO: oops, multiple users
        break;
}

考虑使用带有 DataTable 的 OleDbDataAdapter。

    OleDbCommand command = new OleDbCommand();
    command.Connection = connection;
    command.CommandText = "select * ... ";
    DataTable zDataTable = new DataTable;
    OleDbDataAdapter zDataAdapter = new OleDbDataAdapter;
    zDataAdapter.SelectCommand = command;
    zDataAdapter.Fill(zDataTable);
    int RecordCount = DataTable.Rows.Count;

这样您就不必遍历所有记录来获取记录数。

即使出现错误,using 块也能确保您的数据库对象被关闭和处置。这确保清理这些对象使用的非托管资源。

您可以将连接字符串直接传递给连接的构造函数。同样,命令的构造函数可以采用 sql 语句和连接。

使用带有参数名称和数据类型的 Parameters.Add 的重载。这有助于让我们知道参数的值与数据类型匹配。

因为我们在 select 语句中使用了 Count,所以我们可以使用 ExecuteScalar 并且只提取单个数据而不是整个记录。

当然,在实际应用程序中,您永远不会将密码存储为纯文本。

    private void button1_Click(object sender, EventArgs e)
    {
        int RetVal;
        using (OleDbConnection connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source = C:\Users\RBA\Desktop3\users1.mdb;Persist Security Info=False;"))
        {
            using (OleDbCommand cmd = new OleDbCommand("Select Count(*) From DataData Where [user] = @User And [password] = @password;", connection))
            {
                cmd.Parameters.Add("@User", OleDbType.VarChar).Value = text_Username.Text;
                cmd.Parameters.Add("@Password", OleDbType.VarChar).Value = text_Password.Text;
                connection.Open();
                RetVal = (int)cmd.ExecuteScalar();
            }
        }
        if (RetVal == 1)
            MessageBox.Show("Welcome");
        else
            MessageBox.Show("Login incorrect");
    }

差点忘了!对于 OleDb 提供程序,必须按照它们在 sql 语句中出现的相同顺序将参数添加到参数集合中。此提供程序将不匹配参数名称。