2017-08-30 1 views
0

問題が修正されました。主な問題は、そのウィンドウが閉じられて別のウィンドウが開いた後に消去されたxamlのテキストボックスから情報を取得していたことです。答えは私の他の問題を解決し、私のコードをはるかに簡単で読みやすくしました。とてもありがとう!C#SqlDataReaderが値を見つけられない

私は現在、パーソナルプロジェクト用のカレンダーを作成し、データベースにイベントを追加する作業を行っています。この表には、2つのvarcharsとint(名前、説明、ユーザーID)が格納されています。外部キーであり、ユーザーテーブルにリンクされています。以下のコードを使用して、入力したユーザー名のユーザーIDを取得しようとすると、既存の値が存在しないことがわかります。

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関数を使用してみてください。スカラーを実行すると単一の値が返され、ユーザーIDだけが必要なことがわかります。 このlinkをご覧ください。私はそれが役に立てば幸い

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

GetInt32

+0

ありがとうございます!それは助けてくれましたし、私もリンクを感謝し、それはまた助けになりました! – RButler

1

インデックスは、したがって、あなたの呼び出しが読むべき、per docとして0をベースとしている:

int userid = reader.GetInt32(0); 
1

変更し、これらの行:

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

へ:

var userID = com.ExecuteScalar(); 

理由:

クエリーが単一の値を返す場合は、スカラーを実行するを使用する必要があります。

実行リーダーは、DataReaderの形式でデータのコレクションを返します。 DataReaderは高速であり、必要なデータをデータベースから取得するためにそれらを繰り返し処理できます。接続はデータレアが開いている間は開いたままです。

データベースから単一の値を取得しているだけなので、ExecuteScalarを使用することは理にかなっています。それはより効率的であり、ポイントも重要です。

UserIDのリストを取得していた場合は、DataReaderを使用してUserIDを繰り返し処理することをお勧めします。

+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

関連する問題