4

同じ文字列からIDを取得しようとして、複数のスレッドからこのメソッドを呼び出そうとしました。SqlDataReaderを作成する行で常にこの例外が発生します。

このコマンドに関連付けられている開いているDataReaderがすでにあり、最初に閉じる必要があります。

問題がどこにあるのかわかりません。lock()ステートメントを使用しているので、コマンドを1回だけ使用してから、それを破棄します。データベースプログラミングは初めてなので、エラーがどこにあるのかわかりません。

ありがとう!

public int UsernameGetID(string username)
{
    using (var command = new SqlCommand("SELECT user_id FROM " + ServerConstants.Database.TableUserInformation + " WHERE username = @Username", connection))
    {
        lock (command)
        {
            SqlParameter param = new SqlParameter("@Username", SqlDbType.VarChar, username.Length);
            param.Value = username;
            command.Parameters.Add(param);
            using (SqlDataReader reader = command.ExecuteReader())
            {
                if (reader.Read())
                {
                    return (int)reader[0];
                }
                else
                {
                    // username doesn't exists
                    return 0;
                }
            }
        }
    }
}
4

1 に答える 1

9

メソッド内で新しいコマンドを作成していることを考えると、ロックオンcommandは無意味です。他のコードはそれをロックできません。

ただし、複数のコマンド間で接続を共有しています。それをしないでください-各呼び出しで新しいSqlConnection(ここでもusingステートメントで)を作成します。効率の側面について心配する必要はありません。接続プールが「実際の」ネットワーク接続を処理します。

あなたが望んでいるのは:

using (var connection = new SqlConnection(...))
using (var command = new SqlCommand(..., connection))
{
    connection.Open();
    ...
    using (var reader = command.ExecuteReader())
    {
        return reader.Read() ? (int) reader[0] : 0;
    }
}
于 2012-07-31T22:42:31.583 に答える