3

我目前正在编写一个小型应用程序来跟踪货币进出,这只是为了提高我的一般 C# 技能。对于我的登录屏幕,目前我有以下代码

    private void Login_Load(object sender, EventArgs e)
    {
        // TODO: This line of code loads data into the 'spendingInsAndOutsDataSet.Users' table. You can move, or remove it, as needed.
        this.usersTableAdapter.Fill(this.spendingInsAndOutsDataSet.Users);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        string userNameText = userName.Text;
        string passwordText = password.Text;

        foreach (DataRow row in spendingInsAndOutsDataSet.Users)
        {
            if (row.ItemArray[4].Equals(userNameText) && row.ItemArray[5].Equals(passwordText))
            {
                MessageBox.Show("Login Successful");

                MainGUI newForm = new MainGUI();
                this.Visible = false;
                newForm.Show();
                break;
            }
            else
            {
                userName.Text = String.Empty;
                password.Text = String.Empty;
                MessageBox.Show("Login Failed");
                break;
            }
        }
    }

当登录成功时,我希望将当前 PC 的 MachineName 写入我的 SQL 数据库中用户表中的字段。这样,当我开始创建记录时,我可以快速找到我的 UsersId(这是我的 Transactions 表中的外键)。

我知道您可以使用 System.Enviroments 路径获取活动机器名称,但我不确定如何编写更新。我知道如何使用 SqlCommand 来做到这一点,但我想知道是否有更简单的方法使用我在 ForEach 循环中使用的 DataRows。

在此先感谢,有任何问题请告诉我。

詹姆士

4

2 回答 2

2

在您的 foreach 循环中,在相关行上设置当前 PC 的 MachineName,然后在方法调用结束时设置:

this.usersTableAdapter.Update(this.spendingInsAndOutsDataSet.Users);

这将使用机器名称更新数据库

但是,查看您的代码,我想添加一些额外的评论来改进您所拥有的内容:

您正在加载整个数据表,然后检查它的用户名和密码。实际上,您在数据库中查询用户 ID,加载该单行并检查密码。如果您有很多用户,您当前的实施将产生大量网络流量。

代替:

foreach (DataRow row in spendingInsAndOutsDataSet.Users)

考虑使用类似的东西:

foreach (SpendingInsAndOutsDataSet.UsersRow row in spendingInsAndOutsDataSet.Users)

即数据行对象的强类型版本。这意味着您可以使用:

row.Username.Equals(userNameText) 

代替

row.ItemArray[4].Equals(userNameText) 

此外,如果您预计这将在网络上使用,您应该考虑加密密码。

于 2013-10-08T21:35:21.090 回答
2

假设它是一个 Access 数据库(如果不是,则进行必要的更改):

使用适配器用您的结果填充表格。然后将行列与用户提供的信息进行比较。不要忘记使用参数来避免可能会破坏您的数据库或将您的用户信息暴露给黑客的注入。

DataTable dt = new DataTable();
String sql = "SELECT * FROM users WHERE user = @user and password=@password"
OleDbConnection connection = getAccessConnection();
OleDbDataAdapter da = new OleDbDataAdapter(sql, connection);
da.SelectCommand.Parameters.Add("@user", OleDbType.VarChar).Value = userNameText;
da.SelectCommand.Parameters.Add("@password", OleDbType.VarChar).Value = password.Text;
try
{
   connection.Open();
   da.Fill(dt);
   connection.Close();
}
catch(OleDbException ex)
{
   connection.Close();
   MessageBox.Show(ex.ToString());
}

if(dt.Rows.Count == 1)
    return true; //username && password matches
else if(dt.Rows.Count == 0)
    return false; // does not match

您也可以使用 AddWithValue 作为您的参数。

da.SelectCommand.Parameters.AddWithValue("@user", userNameText);

getAccessConnection() 是一个预定义的 OleDbConnection 函数,它连接到数据库设置并为您创建一个新的连接实例(我为自己创建的)。

public OleDbConnection getAccessConnection()
{
    this.connection = new OleDbConnection();
    this.connection.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" 
            + Classified.SOURCE + ";Jet OLEDB:Database Password=" 
            + Classified.PASS + ";";
    return this.connection;
}

最好为可能加入项目的开发人员创建所有这些功能的类。还要阅读 C# 测试驱动开发。

此外,即使该记录失败,您的循环似乎也会中断,只允许它转到它的第一条记录。

创建自己的数据集并用查询表填充它也很有用。这是一个简短的例子:

DataSet ds = new DataSet();
ds.Tables.Add(dt, "userSearchedTable");
ds.Tables["userSearchedTable"].Rows[0][1].ToString();

然后,您可以在需要时在集合中声明一个特定的数据表。

于 2013-10-08T21:40:44.103 回答