2017-08-30 68 views
0

我的問題已經修復,我的主要問題是從xAMl中的文本框中獲取信息,該信息在該窗口關閉並且另一個打開後被擦除。雖然答案確實解決了我的其他問題,並使我的代碼更加簡單易讀。非常感謝你!c#SqlDataReader未找到值

所以我目前正在爲個人項目建立一個日曆,並且正在致力於向數據庫添加事件,Events的這個表存儲兩個varchars和一個int(名稱,描述,用戶ID),userid是一個外鍵並鏈接到用戶表。當我使用下面的代碼嘗試並拉取用戶輸入的用戶名時,它告訴我沒有現有值。

using (SqlConnection connection = new SqlConnection()) 
     { 

      connection.ConnectionString = 
        "Data Source=calenderserver.database.windows.net;" + 
        "Initial Catalog=Calender;" + 
        "User id=*******;" + 
        "Password=*******;" + 
        "MultipleActiveResultSets = true"; 
      connection.Open(); 

      SqlCommand com = new SqlCommand("Select UserId from Users Where UserName = @user", connection); 
      com.Parameters.AddWithValue("@user", UsernameTextBox.Text); 

      SqlDataReader reader = com.ExecuteReader(); 
      reader.Read(); 
      int userid = reader.GetInt32(1); 

      messages.Text = "Event Added"; 
      SqlCommand command = new SqlCommand("INSERT INTO [Events] VALUES (@eventname, @eventdesc)", connection); 
      command.Parameters.AddWithValue("@eventname", name); 
      command.Parameters.AddWithValue("@eventdesc", description); 
      command.Parameters.AddWithValue("@userid", userid); 
      command.ExecuteNonQuery(); 

      reader.Close(); 
      connection.Close(); 

     } 

即使當我在實際SQL查詢中運行相同的命令時,它也會返回正確的值。

SQL Command

我完全失去了這一點,並檢查了多個來源和解決方案,將真正體會到了幫助。

+3

你可能想從連接刪除您的數據庫密碼串在這個問題..... – MikeTheLiar

+0

你描述你的日曆項目和事件表的很詳細,但你的問題只引用您還沒有描述的用戶表... – Toastrackenigma

+0

@mikeTheLiar不要擔心它是不是實際的帳戶信息,但有人將其更改爲*,這更好。 – RButler

回答

1

嘗試使用ExecuteScalar函數。執行標量返回單個值,我看到您只需要用戶標識。 看看這個link

int userid = (Int32)com.ExecuteScalar();

我希望它可以幫助!在GetInt32

+0

謝謝!它確實有幫助,我也很欣賞鏈接,這也有幫助! – RButler

1

指數從0開始爲per doc,因此您的來電應改爲:

int userid = reader.GetInt32(0); 
1

更改這些行:

 SqlDataReader reader = com.ExecuteReader(); 
     reader.Read(); 
     int userid = reader.GetInt32(1); 

到:

var userID = com.ExecuteScalar(); 

爲什麼:

當您的查詢返回單個值時,應使用執行標量

Execute Reader以DataReader的形式返回數據的集合。 DataReader速度很快,您可以快速迭代它們以從數據庫獲取所需的數據。只要數據讀取器處於打開狀態,連接就會保持打開狀態。

由於您只從數據庫中獲取單個值,因此使用ExecuteScalar是有意義的。這是更高效,也是重點。

如果您正在獲取用戶標識的列表,那麼我建議您使用DataReader來遍歷用戶標識。

+1

不錯,您提供的解決方案,但它會很好,如果您包括***爲什麼***切換到執行標量將解決問題。 –

+0

因爲在他的問題,他的固定可見的用戶名/密碼,是一個更高的優先級;)但是真的,我要闡述 –

+0

如果在SQL表中的用戶ID設置爲自動增量將它仍然能夠被稱爲? – RButler

2

你在做int userid = reader.GetInt32(1); get函數的索引是0,所以你實際上需要int userid = reader.GetInt32(0);所以你得到第一列。

話雖這麼說,是因爲你使用的是第一列的第一個結果,你可以從一個數據讀取器開關簡化代碼使用ExecuteScalar()

 SqlCommand com = new SqlCommand("Select UserId from Users Where UserName = @user", connection); 
     com.Parameters.AddWithValue("@user", UsernameTextBox.Text); 

     int userid = (int)com.ExecuteScalar(); 
+0

謝謝!它幫助了很多!我只是在遇到另一個問題後才解決了我的問題,但它是你的和其他人評論類似的,如果解決方案不是相同的解決方案! – RButler