IDataReader si svuota durante la visualizzazione per la seconda volta
-
06-07-2019 - |
Domanda
Sto ottenendo qualcosa di abbastanza strano mentre provo a leggere alcuni dati usando il connettore MySql .net. Ecco il codice:
IDataReader reader = null;
using (MySqlConnection connection = new MySqlConnection(this.ConnectionString))
{
String getSearch = "select * from organization";
MySqlCommand cmd = new MySqlCommand(getSearch, connection);
cmd.CommandType = CommandType.Text;
connection.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
{
// response write some stuff to the screen (snipped for brevity)
}
}
Se inserisco un punto di interruzione dopo ExecuteReader ed esplodo la visualizzazione dei risultati in Visual Studio (passando il mouse sopra il lettore ed espandendoli), posso vedere le righe restituite dalla query. Se poi lo lascio chiudere ed esplogo di nuovo la visualizzazione dei risultati, ricevo il messaggio "L'enumerazione non ha prodotto risultati".
Sembra che i contenuti del lettore vengano ripristinati non appena vengono visualizzati.
Per quanto riguarda quello che abbiamo provato:
- l'SQL funziona perfettamente direttamente su DB
- Associare i risultati della query direttamente a un datagrid restituisce solo un datagrid vuoto
- ottenuto l'ultima versione del connettore .net
- ha provato su due macchine diverse per escludere eventuali errori locali
Finora non ha funzionato nulla.
Se qualcuno potesse offrire idee o suggerimenti, sarebbe molto apprezzato.
Soluzione
da quanto ho capito, SqlDataReader è destinato a essere utilizzato per un elenco una tantum dei dati restituiti. Una volta passati in rassegna i risultati una volta, l'oggetto ha fatto il suo dovere. Ecco un paio di idee per aggirare questo, l'uno o l'altro dei quali potrebbe risolverlo per te in base alle tue esigenze:
-
Riesegui la query per generare un altro SqlDataReader quando necessario
-
Invece di utilizzare SqlDataReader, archivia i risultati della query originale in una tabella System.Data.Data, dove puoi quindi rileggere e manipolare i dati come preferisci.
Spero che questo aiuti!
Adam
Altri suggerimenti
Poiché un datareader legge le informazioni, il tuo blocco using chiude la connessione al lettore subito dopo aver assegnato il suo valore alla variabile. Ecco un articolo che ti mostra alcuni esempi di codice che potrebbero portarti dove devi essere.
La chiave è che la connessione DEVE essere aperta, quando si tenta di leggere dal lettore.
Ecco la spiegazione:
Questo perché, hai già eseguito il ciclo nel lettore una volta nel debugger (la prima volta che hai espanso la vista). Questo è il modo in cui funzionano i lettori, e da quello che so, non c'è modo di resettare un lettore per andare a leggere di nuovo dall'inizio, tranne l'opzione di riesecuzione:
Devi solo eseguire di nuovo il Linea
cmd.ExecuteReader ();
(a destra fai clic sulla fonte e usando " set dichiarazione successiva " opzione di menu).
Questo è il comportamento dei lettori di dati. Se l'hai già fatto, non puoi tornare indietro. Devi eseguire nuovamente il comando e recuperarne uno nuovo.
Se è necessario utilizzare i dati dopo aver chiuso il lettore, è possibile scegliere di utilizzare un Typed DataSet
o il DataSet
non tipizzato come specificato in Adam answer .
A proposito, ecco alcune ottimizzazioni
che potresti fare:
- Sposta il lettore all'interno di
Connessione
usando il blocco per farlo uscire dal campo di applicazione dopo aver terminato usandolo (una volta terminato l'utilizzo blocco, la connessione verrà chiusa e non potrai comunque usarlo, quindi non ha senso lasciarlo fuori) - Esegui
ExecuteReader
in un altro bloccoutilizzando
(in quanto implementaIDisposable
) e fa la stessa cosa con il comando SqlIDisposable
interfaccia) - Non recuperare tutti i campi dal database