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.

getuserメソッドは次のとおりです。

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

なぜあなたはcmd.ExecuteReader()声明usingの中で、そしてcmd.ExecuteNonQuery();次の行でそれをするのですか?

ExecuteReader()結果を確認せずにデータベース呼び出しから戻るだけなので、なぜを使用するのか-ExecuteNonQueryこれで十分です。

于 2013-02-23T13:09:07.777 に答える
1

これがActivateUserの問題です。

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

SqlCommandオブジェクトでリーダーを開いてから、最初にリーダーを閉じずにそのコマンドオブジェクトで別のクエリを実行することはできません。これは、最後の「}」まで発生しません。実際、この場合は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 に答える