2

次のコードがあります。

using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
   connection.Open();
   SqlCommand select = new SqlCommand("SELECT RTRIM(LTRIM(PART_NO)) AS PART_NO, record FROM [RMAData].[dbo].[IMPORTING_ORDER_EDI] WHERE sessionID = '" + Session.SessionID + "'", connection);

   SqlDataReader reader = select.ExecuteReader();

   if (reader.HasRows)
   {
      while (reader.Read())
      {
         if (!currentPart.IsActive)
         {
            // this part is not active, set the active flag in sql to 0
            SqlCommand update = new SqlCommand("UPDATE [RMAData].[dbo].[IMPORTING_ORDER_EDI] SET valid = 0, active = 0 WHERE record = " + reader["record"].ToString() + ";", connection);

            update.ExecuteNonQuery();
         }
         else
         {
            ///blah
         }
      }

      reader.Close();
   }
}

しかし、これにより次の例外が発生します...

System.InvalidOperationException: このコマンドに関連付けられている開いている DataReader が既に存在します。これを最初に閉じる必要があります。

返された各行を読み取り、データの検証を行い、必要に応じて更新を行ってから、次のレコードに進む必要があります。SqlCommandwhile ループを使用できない場合、どうすればこれを達成できreader.Read()ますか?

4

3 に答える 3

6

接続文字列を修正するのと同じくらい簡単です:

MultipleActiveResultSets=True を接続文字列に追加します

于 2013-02-21T15:31:07.580 に答える
3

代替手段は、MultipleActiveResultSets=True を追加しないことです。これを行うと、パフォーマンスがわずかに低下します。つまり、次のようになります。

using (SqlConnection connection = new ...))
{
   connection.Open();
   SqlCommand select = new SqlCommand(...);

   SqlDataReader reader = select.ExecuteReader();

   var toInactivate = new List<string>();

   if (reader.HasRows)
   {
      while (reader.Read())
      {
         if (!currentPart.IsActive)
         {
            toInactivate.Add(reader["record"].ToString());
         }
         else
         {
            ///blah
         }
      }

      reader.Close();
   }

   SqlCommand update = new SqlCommand("UPDATE ... SET valid = 0, active = 0 " +
       "WHERE record IN(" + string.Join(",", toInactivate) +  ");", connection);

   update.ExecuteNonQuery();
}

これには、必要なすべてのレコードを単一の SQL ステートメントで更新できるという利点があります。

そしてもちろん、EF と Linq を使用すると、全体が非常にきれいになります。

于 2013-02-21T18:13:20.353 に答える
3

接続の複数のインスタンスを作成する必要があります。
一般に、接続に対して実行できるコマンドは1つだけか


@grantThomasの提案に従って
実行できるため、または、次のように複数の接続を使用できます

using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
   connection.Open();
   SqlCommand select = new SqlCommand("SELECT RTRIM(LTRIM(PART_NO)) AS PART_NO, record FROM [RMAData].[dbo].[IMPORTING_ORDER_EDI] WHERE sessionID = '" + Session.SessionID + "'", connection);

   SqlDataReader reader = select.ExecuteReader();

   if (reader.HasRows)
   {
      while (reader.Read())
      {
         if (!currentPart.IsActive)
         {
            // this part is not active, set the active flag in sql to 0
            using (SqlConnection connection1 = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
           {
               SqlCommand update = new SqlCommand("UPDATE [RMAData].[dbo].[IMPORTING_ORDER_EDI] SET valid = 0, active = 0 WHERE record = " + reader["record"].ToString() + ";", connection1);


            update.ExecuteNonQuery();
           }
         }
         else
         {
            ///blah
         }
      }

      reader.Close();
   }
}
于 2013-02-21T15:37:39.953 に答える