2016-04-23 46 views
-3

当我运行这个动作时,我收到了这条消息:“已经有一个打开的DataReader与这个Command相关联,必须先关闭它。”一个开放的数据读取器

我的代码是:公共无效UpdatePoints(字符串rightScore,串rightWinner) {

cmd.CommandText = "select * from Users_Details"; 
    cmd.Connection = connection; 
    connection.Open(); 
    rdr = cmd.ExecuteReader(); 

    while (rdr.Read()) 
    { 

     int points=0; 
     string sql; 
     string hisScore = (string)rdr["lastbetscore"]; 
     string hisWinner = (string)rdr["lastbetwinner"]; 
     if (rightScore == hisScore) 
      points = points + 30; 
     if (rightWinner == hisWinner) 
     { 
      points = points + 20; 
     } 

     sql = "update Users_Details set lastgame_points='" + points + "', gamesplayed='" + ((int)rdr["gamesplayed"] + 1) + "',currentpoints='" + ((int)rdr["currentpoints"] + points) + "',pointsPG='" + (((int)rdr["currentpoints"] + points)/((int)rdr["gamesplayed"] + 1)) + "' where username='" + (string)rdr["username"] + "'"; 
     cmd.CommandText = sql; 
     cmd.ExecuteScalar(); 
    } 
    rdr.Close(); 
    connection.Close(); 
} 

回答

0

你应该创造而不是重用旧这里一个新的命令实例:

sql = "update Users_Details set lastgame_points='" + points + "', gamesplayed='" + ((int)rdr["gamesplayed"] + 1) + "',currentpoints='" + ((int)rdr["currentpoints"] + points) + "',pointsPG='" + (((int)rdr["currentpoints"] + points)/((int)rdr["gamesplayed"] + 1)) + "' where username='" + (string)rdr["username"] + "'"; 
cmd.CommandText = sql; 
cmd.ExecuteScalar(); 

在另外,阅读命令参数,自己格式化SQL字符串,可以打开SQL注入攻击。

3

错误消息是非常具体的关于你做错了什么。您不能重复使用该命令或连接的另一个命令您正在从它读取数据。您必须首先将所有数据读取到List或其他数据结构,然后使用此List的每个元素更新db。

另外,考虑在交易

var transaction = connection.BeginTransaction(); 
... 
transaction.Commit(); 

这会加速你的更新,因为交易将被创建并COMMITED只有一次,但其它方式交易将隐含在每个更新

创建执行你的语句
+0

我添加了它,但仍然收到错误消息 –

+0

现在,它会打印出“已经有一个与此连接关联的打开的DataReader,必须先关闭”。 ?而不是“命令”? –

+0

我的第一个答案是错误的,因为不仅可以重用命令,还可以重用连接。请查看更正的答案。 –