2016-04-29 13 views
0

SQLサーバーからの受信データをチェックし、それをテキストフィールドと比較し、重複がない場合は非問合せを実行する単純なループを作成します。C#のこのコマンドエラーに関連付けられている開いているデータレア

私はこのコードを書いた:

try 
{ 
    bool exists = false; 
    conn = new SqlConnection(DBConnectionString); 

    SqlCommand check_user = new SqlCommand("SELECT usrEmail FROM tblUsers", conn); 
    SqlCommand add_user = new SqlCommand("INSERT INTO tblUsers (usrEmail, usrPassword, usrRealname, usrIsowner) VALUES (@email, @pass, @name, @owner)", conn); 
    // (I have removed all the paramaters from this code as they are working and irrelevant) 
    conn.Open(); 

    SqlDataReader check = check_user.ExecuteReader(); 

    while (check.Read()) 
    { 
     if (Convert.ToString(check[0]) == UserEmail.Text) 
     { 
      MessageBox.Show("The email you entered already exists in the system."); 
      exists = true; 
      break; 
     } 
    } 

    if (exists == false) 
    { 
     add_user.ExecuteNonQuery(); 
    } 
    else 
    { 
     return; 
    } 
} 
catch (Exception ex) 
{ 
    MessageBox.Show("There was a problem uploading data to the database. Please review the seller's details and try again. " + ex.Message); 
    return; 
} 
finally 
{ 
    conn.Close(); 
} 

私はブレークポイントを使用してコードをwhileループの罰金を実行しますが、それはは、ExecuteNonQueryコマンドに到達したとき、それはエラーメッセージを返すことを見た:

このコマンドに関連付けられている開いているデータレアが既にあります。 を最初に閉じる必要があります。

私は試してみましたe check.Close();コマンドですが、私がそうすると、理解を越える理由で、重複した電子メールエラーメッセージが突然止まってしまいます。 さらに、データが実際にデータベースに送信された(私はSQL Server Management Studioで見た)修正プログラムがありましたが、エラーメッセージが表示されました...これは見知らぬものでした。この機能ではLASTです。それがうまくいったら、なぜそれはキャッチに行くのですか?

私はサイトで回答を検索しましたが、最も一般的な回答はMARS(これは何であるかわかりません)またはこのケースでは使用したくないデータセットです。

ここには簡単な解決策がありますか?私はコードで何かを忘れましたか?

+0

ループの後にこの行を追加する_if(!check.IsClosed){check.Close(); } _ –

答えて

1

方法うち最も単純には、次のようになります。このコードのいくつかの深刻な問題がある、と述べた

using(SqlDataReader check = check_user.ExecuteReader()) 
{ 
    while (check.Read()) 
    { 
     if (Convert.ToString(check[0]) == UserEmail.Text) 
     { 
      MessageBox.Show("The email you entered already exists in the system."); 
      exists = true; 
      break; 
     } 
    } 
} 

まず、すべてユーザーを読んで、電子メールアドレスがすでに使用されていることを確認する必要はありません。 select count(*) from tblUsers where usrEmail = @emailは大丈夫です...

...かどうか、競合状態の可能性があります。あなたがするべきことは、usrEmail列に一意の制約を追加し、違反をキャッチしているのはinsert into tblUsersだけです。または、あなたが気に入ったらmergeを使うことができます。

次に、実際にデータアクセスコードを全面に渡すことは望ましくありません。それを少なくとも別のクラス/メソッドに分解してください。

+0

魅力的な作品です!ありがとうございました! –

関連する問題