4

我试图从多个线程中调用此方法,试图从同一字符串中获取 ID。我总是在创建 SqlDataReader 的那一行遇到这个异常:

已经有一个与此命令关联的打开的 DataReader,必须先关闭它。

我不知道问题出在哪里。我正在使用 lock() 语句,所以我只使用该命令一次,然后将其处理掉。对数据库编程有点陌生,所以我不知道我的错误在哪里。

谢谢!

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 回答