2012-10-19 16 views
40

Normalmente utilizzato DataSet perché è molto flessibile. Recentemente mi è stata assegnata l'attività di ottimizzazione del codice. Per ridurre gli accessi al database, sto cambiando due query in un'unica procedura. una query restituisce il count e l'altro restituisce il actual data. Cioè, My stored procedure restituisce due tabelle. Ora so come leggere entrambe le tabelle usando DataSets, ma ho bisogno di leggere entrambe le tabelle usando DataReader. Alla ricerca di quello ho trovato This.Tabella Multipli in DataReader

seguo l'articolo e scritto il mio codice come questo:

dr = cmd.ExecuteReader(); 
while (dr.Read()) 
{ 


} 
if (dr.NextResult()) // this line throws exception 
{ 
    while (dr.Read()) 
{ 

Ma sto un'eccezione a dt.NextResult. Eccezione è:

Ho anche tentato di Google sopra l'errore, ma ancora non in grado di risolvere il problema. Qualsiasi aiuto sarà molto apprezzato. Ho bisogno di leggere più tabelle usando datareader, è possibile?

+1

Quello che non capisco è: "una query restituisce il conteggio e gli altri restituisce i dati effettivi cioè la mia stored procedure restituisce due tavoli" _ _ Perché è il conteggio (che è un valore scalare) a ** tabella **? –

+0

Sì, è un valore scalare ma la procedura memorizzata viene scritta utilizzando query dinamiche. entrambe le query sono molto grandi e le query vengono scritte come varchar e quindi, alla fine, eseguite utilizzando Exec. Se chiamo Query query come query secondaria della query di dati effettiva, la dimensione della variabile di query è molto grande ed è Eseguita con errori. Quindi per evitare questo ho scritto due query diverse questa è la ragione per cui Count viene anche da una tabella (seconda tabella). Spero di averlo chiarito. –

risposta

50

Prova questo, perché questo chiude la connessione, lettore di dati e il comando una volta compito di superare, in modo che questo non darà datareader vicino eccezione

anche controlli come questo if(reader.NextResult()) per controllare ci si trova accanto risultato,

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"); 
       } 
      } 
     } 
    } 
} 
+0

y c'è - 1? –

+0

Non ti ho votato. Ma il mio codice è proprio come il tuo. –

+0

@ muhammadkashif- il tuo errore è causato dal fatto che o la tua connessione è chiusa o datareader chiusa, quindi è meglio controllare anche questo ... controlla anche per nextresultset in se clausola come ho fatto che ti aiuta anche ... –

11

Ho provato a riprodurre questo problema (anche perché non ho usato più tabelle in un lettore prima). Ma funziona come previsto, quindi presumo che tu abbia omesso il codice relativo.

Ecco il mio codice di prova:

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]); 
       } 
      } 
     } 
    } 
} 
+0

Grazie, il mio problema è risolto, votando per i tuoi sforzi. –

+0

Se desidero utilizzare DataTable.Load() anziché eseguire il ciclo del lettore, la seconda tabella viene popolata. Qualche indizio su questo? – Biki

+3

Finalmente ho avuto l'idea. Se utilizziamo DataTable.Load(), non è necessario utilizzare rdr.NextResult(), poiché viene preso in considerazione implicitamente. – Biki