在数据访问方法中调用两个方法的问题

时间:2013-02-23 13:04:57

标签: c# sql-server sqldatareader sqlconnection sqlcommand

我有这个方法:

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())
                        {...

3 个答案:

答案 0 :(得分:1)

你的问题就在这里。

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

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

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

答案 1 :(得分:1)

为什么你在cmd.ExecuteReader()语句中using,然后在下一行cmd.ExecuteNonQuery();

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

答案 2 :(得分:1)

这是ActivateUser中的问题:

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

您无法在SqlCommand对象上打开Reader,然后在没有先关闭Reader的情况下对该命令objct执行另一个查询 - 直到最后一个“}”才会发生。 实际上我不确定你在这种情况下甚至需要读者 - 你是否可以从你的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

你也可以为nonquery,nonreader等编写简单的包装器。