Y at-il un moyen d'avoir une SqlConnection qui écrira pendant qu'un DataReader associé est ouvert?

Ou quelle est la manière recommandée de lire et d'écrire en même time? Avoir deux connections ouvertes est le seul moyen? C'est sur une application Windows Forms C # (.NET 3.5)

using (SqlConnection conn = new SqlConnection(connStr)) { SqlCommand cmdRead = new SqlCommand("select stools from foo", conn); SqlDataReader rdr = cmdRead.ExecuteReader(); SqlCommand cmdWrite = new SqlCommand("insert into bar values (@beer)", conn); SqlParameter beer = new SqlParameter("@beer", SqlDbType.Int); cmdWrite.Parameters.Add(beer); while(rdr.Read()) { int stools = rdr.GetInt32(0); cmdWrite.Parameters["@beer"].value = stools; //Next line fails for an open data reader associated to the "command" cmdWrite.ExecuteNonQuery(); } rdr.Close() } 

Ceci, OTOH, fonctionne, mais me semble moche (en plus d'ouvrir une connection supplémentaire)

 using (SqlConnection connR = new SqlConnection(connStr)) { using (SqlConnection connW = new SqlConnection(connStr)) { SqlCommand cmdRead = new SqlCommand("select stools from foo", connR); SqlDataReader rdr = cmdRead.ExecuteReader(); SqlCommand cmdWrite = new SqlCommand("insert into bar values (@beer)", connW); SqlParameter beer = new SqlParameter("@beer", SqlDbType.Int); cmdWrite.Parameters.Add(beer); while(rdr.Read()) { int stools = rdr.GetInt32(0); cmdWrite.Parameters["@beer"].value = stools; cmdWrite.ExecuteNonQuery(); } rdr.Close() } } 

Dans ce cas simple, lisez tous les tabourets, stockez-les dans une list, fermez le lecteur, puis écrivez-les (cela fonctionnera tant qu'il n'y a pas beaucoup de tabourets dans la database), mais dans des cas plus complexes, cela devient difficile. memory faim, donc ce n'est pas non plus souhaitable.

Avec SQL 2005 et versions ultérieures, vous pouvez utiliser plusieurs sets de résultats actifs (MARS):

http://msdn.microsoft.com/en-us/library/ms345109%28SQL.90%29.aspx

http://msdn.microsoft.com/en-us/library/ms131686.aspx

Pour que cela fonctionne, vous devez l'activer dans votre string de connection.

Pourquoi ne pas avoir deux methods: une pour lire et une pour écrire, chacune utilisant sa propre connection tirée du pool de connections.

En train de lire

 using (SqlConnection conn = new SqlConnection(connStr)) using (SqlCommand cmdRead = new SqlCommand("select stools from foo", conn)) { conn.Open(); using (SqlDataReader rdr = cmdRead.ExecuteReader()) { while(rdr.Read()) { int stools = rdr.GetInt32(0); } } } 

L'écriture

 using (SqlConnection conn = new SqlConnection(connStr)) using (SqlCommand cmdWrite = new SqlCommand("insert into bar values (@beer)", conn)) { conn.Open(); SqlParameter beer = new SqlParameter("@beer", SqlDbType.Int); cmdWrite.Parameters.Add(beer); cmdWrite.Parameters["@beer"].value = stools; cmdWrite.ExecuteNonQuery(); } 

Et puis appelez-les sur différents threads. Cela rend les methods plus claires et plus spécifiques.

Vous ne pouvez pas écrire pendant que le DataReader est ouvert, créer une deuxième connection est nécessaire dans cette situation, et à mon humble avis, ce n'est pas un problème de design.

Eh bien, la question évidente est pourquoi faites-vous cela dans le code du tout?

Vous select une table pour l'écrire dans une autre, ce qui me pousse à insert une requête.

Sans doute l'exemple du monde réel est plus complexe, auquel cas vous avez besoin de deux connections parce que les gestionnaires de données travaillent en maintenant la connection ouverte jusqu'à ce que vous ayez terminé et c'est plus ou less cela.