La connection n'a pas été fermée, l'état actuel de Connection est une erreur ouverte dans la boucle foreach

J'ai une application web en utilisant une checkboxlist databound. J'ai mis à jour une procédure stockée que j'ai placée dans une boucle foreach. Si une CheckboxList est cochée, la mise à jour est correcte, mais si j'en ai plusieurs vérifiées, la connection est ouverte. J'ai essayé un try{}catch{}finally{} mais ça me donne toujours la même erreur

 CultureInfo provider = CultureInfo.InvariantCulture; System.Globalization.DateTimeStyles style = DateTimeStyles.None; DateTime dt; DateTime.TryParseExact(datepicker.Text, "mmddy", provider, style, out dt); int i = Int32.Parse(amount.Text); SqlConnection conn = new SqlConnection(GetConnectionSsortingng()); SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; foreach (ListItem item in CheckBoxList1.Items) { if(item.Selected) { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "[dbo].[AccountCode_Update]"; cmd.Parameters.AddWithValue("@Batch_Num", SqlDbType.Int).Value = i; cmd.Parameters.AddWithValue("@Batch_Date", SqlDbType.DateTime).Value = dt; cmd.Parameters.AddWithValue("@Account_Code", SqlDbType.VarChar).Value = BatchCodeList.SelectedValue; conn.Open(); cmd.ExecuteNonQuery(); } } conn.Close(); 

SQL

 CREATE TABLE AccountTable ( RowID int IDENTITY(1, 1), AccountID varchar(2), AccountName varchar(50), SeqNum int, SeqDate datetime ) CREATE PROCEDURE [AccountCode_Update] ( @Batch_Num int, @Batch_Date datetime, @Account_Code varchar(2) ) AS SET NOCOUNT ON BEGIN UPDATE AccountTable SET SeqNum = @Batch_Num, SeqDate = @Batch_Date WHERE AccountID = @Account_Account_Code END 

Déplacez votre conn.Open(); appelez avant votre boucle foreach .

 SqlConnection conn = new SqlConnection(GetConnectionSsortingng()); SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; conn.Open(); foreach (ListItem item in CheckBoxList1.Items) { if(item.Selected) { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "[dbo].[AccountCode_Update]"; cmd.Parameters.AddWithValue("@Batch_Num", SqlDbType.Int).Value = i; cmd.Parameters.AddWithValue("@Batch_Date", SqlDbType.DateTime).Value = dt; cmd.Parameters.AddWithValue("@Account_Code", SqlDbType.VarChar).Value = BatchCodeList.SelectedValue; cmd.ExecuteNonQuery(); } } conn.Close(); 

Qu'est-ce qui se passe, c'est que vous appelez conn.Open() d'une connection qui est déjà ouverte et il génère une erreur. C'est pourquoi le premier appel fonctionne et les suivants échouent.

Jetez un coup d'oeil à la documentation MSDN pour la méthode Open() . Il a quelques exemples de ce qui va provoquer des exceptions.

Dans ce cas

InvalidOperationException

Impossible d'ouvrir une connection sans spécifier une source de données ou un server. ou La connection est déjà ouverte.

Fermez la connection! En outre, vous devrez effacer les parameters de command dans chaque boucle.

  foreach (ListItem item in CheckBoxList1.Items) { if(item.Selected) { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "[dbo].[AccountCode_Update]"; cmd.Parameters.AddWithValue("@Batch_Num", SqlDbType.Int).Value = i; cmd.Parameters.AddWithValue("@Batch_Date", SqlDbType.DateTime).Value = dt; cmd.Parameters.AddWithValue("@Account_Code", SqlDbType.VarChar).Value = BatchCodeList.SelectedValue; conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); cmd.Parameters.Clear(); // you need to clear previous parameters } } 

MISE À JOUR: OK. J'ai vu la réponse de @ Krik, et je dois décrire:

L'une des règles de base dans le travail avec ADO.NET est la suivante: Ouvrez une connection AS TARD AS POSSIBLE, et fermez-le dès que possible. Donc, vous ne devriez pas garder ouverte une connection à travers une boucle, puisque vous effectuez des opérations non-database ici. Comme l'effacement des parameters de la command et son remplissage. Donc, ce serait idéal:

 conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); 

conn.Open devrait être à l'extérieur foreach.

Une fois ouvert il essaie d'ouvrir à nouveau sur le deuxième article. Sélectionné.