开放式数据阅读器

时间:2016-04-23 12:18:57

标签: c#

我在运行操作时收到此消息:“已经有一个与此命令关联的打开的DataReader必须先关闭。”

我的代码是:public void UpdatePoints(string rightScore,string 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();
}

2 个答案:

答案 0 :(得分:3)

错误消息非常具体,说明你做错了什么。您无法重新使用命令或连接来执行另一个命令,而您正在从中读取数据。您必须首先将所有数据读取到某个List或其他数据结构,然后使用此List的每个元素更新数据库。

另外,考虑在事务中执行你的陈述

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

这将加快您的更新,因为交易将被创建并仅提交一次,但其他方式将在每次更新

上隐含地创建交易

答案 1 :(得分:0)

您应该创建一个新的Command实例,而不是在这里重用旧实例:

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注入攻击。