J'utilise normalement DataSet
car il est très flexible. Récemment, on m'a assigné une tâche d'optimisation de code. Pour réduire les accès à la base de données, je modifie deux requêtes dans une procédure. une requête renvoie le count
et l'autre renvoie le actual data
. C'est mon stored procedure
renvoie deux tables. Maintenant, je sais lire les deux tables en utilisant DataSets
, mais j'ai besoin de lire les deux tables en utilisant DataReader
. A la recherche de cela, j'ai trouvé This .
Je suis l'article et j'ai écrit mon code comme ceci:
dr = cmd.ExecuteReader();
while (dr.Read())
{
}
if (dr.NextResult()) // this line throws exception
{
while (dr.Read())
{
Mais je reçois une exception à dt.NextResult. L'exception est:
Invalid attempt to call NextResult when reader is closed.
J'ai également googlé au-dessus de l'erreur, mais toujours pas en mesure de résoudre le problème. Toute aide sera très appréciée. Je dois lire plusieurs tables en utilisant datareader
, est-ce possible?
Essayez ceci car cela fermera la connexion, le lecteur de données et la commande une fois la tâche terminée, de sorte que cela ne donnera pas d'exception de fermeture du lecteur de données
Vérifiez également comme ceci if(reader.NextResult())
pour vérifier qu'il y a un résultat suivant,
using (SqlConnection connection = new SqlConnection("connection string here"))
{
using (SqlCommand command = new SqlCommand
("SELECT Column1 FROM Table1; SELECT Column2 FROM Table2", connection))
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
MessageBox.Show(reader.GetString(0), "Table1.Column1");
}
if(reader.NextResult())
{
while (reader.Read())
{
MessageBox.Show(reader.GetString(0), "Table2.Column2");
}
}
}
}
}
J'ai essayé de reproduire ce problème (également parce que je n'ai jamais utilisé plusieurs tableaux dans un lecteur auparavant). Mais cela fonctionne comme prévu, donc je suppose que vous avez omis le code associé.
Voici mon code de test:
using (var con = new SqlConnection(Properties.Settings.Default.ConnectionString))
{
using (var cmd = new SqlCommand("SELECT TOP 10 * FROM tabData; SELECT TOP 10 * FROM tabDataDetail;", con))
{
int rowCount = 0;
con.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
String object1 = String.Format("Object 1 in Row {0}: '{1}'", ++rowCount, rdr[0]);
}
if (rdr.NextResult())
{
rowCount = 0;
while (rdr.Read())
{
String object1 = String.Format("Object 1 in Row {0}: '{1}'", ++rowCount, rdr[0]);
}
}
}
}
}
J'ai construit sur la réponse de Pranay Rana parce que j'aime la garder aussi petite que possible.
string rslt = "";
using (SqlDataReader dr = cmd.ExecuteReader())
{
do
{
while (dr.Read())
{
rslt += $"ReqID: {dr["REQ_NR"]}, Shpr: {dr["SHPR_NR"]}, MultiLoc: {dr["MULTI_LOC"]}\r\n";
}
} while (dr.NextResult());
}