2013-10-08 14 views
2

我目前正在編寫一個小應用程序來跟蹤貨幣輸入和輸出,這只是爲了提高我的一般C#技能。對於我的登錄屏幕目前我有以下代碼C#登錄屏幕 - 在SQL表和更新字段中查找用戶

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; 
      } 
     } 
    } 

我所希望做當登錄SUCESSFUL是當前PC的計算機名寫一個字段中的用戶表中我的SQL數據庫。這樣當我開始創建記錄時,我可以快速找到我的UsersId(這是我的Transactions表中的外鍵)。

我知道你可以使用System.Enviroments路徑獲得活動機器名稱,但我不確定如何去編寫更新。我知道如何使用SqlCommand來做到這一點,但我想知道是否有更簡單的方法來使用我在ForEach循環中使用的DataRows。

在此先感謝,有任何問題讓我知道。

詹姆斯

+3

使用'SqlCommand',不要試圖讓自己更難,你正試圖走下更糟糕的**路徑,而不是*更好*路徑 – Jason

+0

謝謝你的迴應賈森。我目前已將應用程序設置爲使用SqlCommand,但如果有人仍然知道從DataSet訪問特定數據行的方式,我將非常感謝。 – jeastham1993

+0

如果結果存在而不是全部返回,您最好提問數據庫。分開您想要實現的功能。 1.將密碼存儲在數據庫中時至少對密碼進行哈希處理 2.創建一個SQL命令,該命令將用戶名/密碼(散列)作爲參數並獲取ID行 3.如果ID行爲空 - 用戶wasn發現 - 如果它是一個有效的整數 - 那麼它是 – tsells

回答

2

假設它是一個Access數據庫(如果沒有,那麼進行必要的更改):

使用適配器來填充表與你的結果。然後將行列與用戶提供的信息進行比較。不要忘記使用參數來避免可能會破壞數據庫或將用戶信息暴露給黑客的注入。

DataTable dt = new DataTable(); 
String sql = "SELECT * FROM users WHERE user = @user and [email protected]" 
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(); 

然後你可以在需要時聲明一個特定的數據表。

+0

高超的迴應,感謝所有的信息。如果我可以安全的話,另一個問題就是我寫的代碼。我很欣賞我需要加密密碼列,但是有沒有明顯的安全漏洞? – jeastham1993

+0

http://stackoverflow.com/questions/1678555/password-encryption-decryption-code-in-net –

+0

你會想要學習如何解開密碼以將其與用戶輸入進行比較。 –

2

在你的foreach循環,設置相關行當前PC的計算機名,然後在方法調用的末尾:

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

這將機器名

更新數據庫

但是看看你的代碼還有一些額外的意見使我想補充,以改善你有什麼:

您正在載入t他整個數據表,然後檢查它的用戶名和密碼。真的,你查詢數據庫中的用戶ID,加載單行並檢查密碼。如果你有很多用戶,你當前的實現會創建大量的網絡流量。

相反的:

foreach (DataRow row in spendingInsAndOutsDataSet.Users) 

考慮使用類似:

foreach (SpendingInsAndOutsDataSet.UsersRow row in spendingInsAndOutsDataSet.Users) 

即強類型數據行對象的版本。這意味着您可以使用:

row.Username.Equals(userNameText) 

,而不是

row.ItemArray[4].Equals(userNameText) 

此外,如果你正期待這將在網絡上使用,你應該看看加密密碼。

+0

感謝您的迴應:)。我知道密碼的加密只是還沒有完成是 – jeastham1993