0

我有这个方法:

public bool ActivateUser(string username, string key)
        {
            var user = this.GetUser(username, true);

            if (user != null)
            {
                if (user.NewEmailKey == key)
                {
                    string query = "usp_ActivateUser";
                    using (SqlConnection conn = new SqlConnection(connectionString))
                    {
                        using (SqlCommand cmd = new SqlCommand(query, conn))
                        {
                            cmd.CommandType = CommandType.StoredProcedure;
                            cmd.Parameters.AddWithValue("@p_Username", username);
                            cmd.Parameters.AddWithValue("@p_LastModifiedDate", DateTime.Now);

                            conn.Open();

                            using (SqlDataReader reader = cmd.ExecuteReader())
                            {
                                cmd.ExecuteNonQuery();
                                return true;
                            }
                        }
                    }
                }
                else
                    return false;
            }
            else
                return false;

        }

如您所见,我首先调用 GetUser() 方法来获取用户,然后将数据用于另一个数据库调用。但是出了点问题。

There is already an open DataReader associated with this Command which must be closed first.

这是获取用户方法:

public User GetUser(string username, bool nonMembershipUser)
        {
            string query = "usp_GetUser";
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = new SqlCommand(query, conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@p_Username", username);
                    conn.Open();

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {...
4

3 回答 3

2

你的问题就在这里。

  using (SqlDataReader reader = cmd.ExecuteReader())
        {
          cmd.ExecuteNonQuery();
          return true;
        }

您正在调用cmd.ExecuteNonQuery(),但该命令已被此 using 块内的阅读器使用。

由于您的代码对读者并没有真正做任何有意义的事情,为什么不完全删除该块并调用cmd.ExecuteNonQuery()

于 2013-02-23T13:08:55.490 回答
1

这就是问题,在 ActivateUser 中:

using (SqlDataReader reader = cmd.ExecuteReader())
                            {
                                cmd.ExecuteNonQuery();
                                return true;
                            }

您不能在 SqlCommand 对象上打开 Reader,然后在没有先关闭 Reader 的情况下对该命令对象执行另一个查询 - 这直到最后一个“}”才会发生。实际上,在这种情况下,我不确定您是否甚至需要阅读器-您是否可能从 GetUser 函数中复制/粘贴?你只需要

cmd.ExecuteNonQuery();
return true;

另外,我会考虑将执行阅读器、查询等的代码包装到一些函数中,以便您可以重用它们。这是我通常用作读者包装的内容:

public static DataTable ExecuteReader (string query,CommandType commType, params SqlParameter[] Paramerters)
{
   try
   {
      using (SqlConnection conn = new SqlConnection("your connection string here")
      {
          conn.Open();
          using (SqlCommand comm = new SqlCommand(conn,query))
          {
             conn.CommandType=commType;
             if (Parameters!=null) comm.Parameters.AddRange(Parameters);
             DataTable dt = new DataTable();
             using (SqlDataReader reader = comm.ExecuteReader())
             {
                dt.Load(reader);
             }
            return dt;
         }//end using command
     }//end using connection
}
 catch(Exception)
{
         throw;
}
}//end function

您也可以为非查询、非阅读器等编写简单的包装器。

于 2013-02-23T13:18:12.953 回答
1

你为什么cmd.ExecuteReader()using声明中这样做,然后cmd.ExecuteNonQuery();在下一行?

为什么要使用ExecuteReader()at ,因为您只是从数据库调用返回而不检查结果 -ExecuteNonQuery就足够了。

于 2013-02-23T13:09:07.777 回答