Come restituire un MySqlDataReader prima che il lettore venga chiuso [duplicato]
-
11-12-2019 - |
Domanda
Ok, il mio codice è attualmente:
public MySqlDataReader CreateQuery(string queryString, string connectionString )
{
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
using (MySqlCommand command = new MySqlCommand(queryString, connection))
{
command.Connection.Open();
command.ExecuteNonQuery();
MySqlDataReader reader = command.ExecuteReader();
return reader;
}
}
}
In un'altra funzione, ho:
using(MySqlDataReader readers = _connection.CreateQuery(query, connectString))
Attualmente, in questa forma, quando restituisco il lettore in un lettore, non vi è alcun valore.Ho esaminato e verificato che al momento della restituzione il lettore contenesse le informazioni corrette.Eppure i lettori non hanno valori.Probabilmente mi sto perdendo qualcosa di completamente stupido.Ma ogni aiuto in questo sarà apprezzato.Grazie!
Soluzione
Con il comando using, il codice eliminerà effettivamente la connessione e il comando prima che il controllo venga restituito al chiamante.Essenzialmente l'oggetto connessione e l'oggetto comando creati nelle istruzioni using vengono eliminati prima che il codice chiamante sia in grado di utilizzarlo, quindi non è più utilizzabile.
Probabilmente vorrai fare qualcosa con i risultati della query piuttosto che con il lettore stesso.Magari caricarlo in una tabella?Qualcosa di simile a:
public DataTable CreateQuery(string queryString, string connectionString )
{
DataTable results = new DataTable("Results");
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
using (MySqlCommand command = new MySqlCommand(queryString, connection))
{
command.Connection.Open();
command.ExecuteNonQuery();
using (MySqlDataReader reader = command.ExecuteReader())
results.Load(reader);
}
}
return results;
}
Altri suggerimenti
Invece di restituire il Datareader
oppure copiare tutti i record in una memoria DataTable
che restituisci nel suo insieme, potresti restituire an IEnumerable<IDataRecord>
che è l'interfaccia di base a DataReader
strumenti di registrazione.
Quindi questo dovrebbe funzionare dal momento che yield
provoca il Connection
per mantenersi in vita:
public IEnumerable<IDataRecord> CreateQuery(string queryString, string connectionString)
{
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
using (MySqlCommand command = new MySqlCommand(queryString, connection))
{
command.Connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return (IDataRecord)reader;
}
}
}
}
}
Se vuoi ad esempio prendi solo i primi 5 record:
var records = CreateQuery("SELECT * FROM ais.country;", Properties.Settings.Default.MySQL).Take(5);
foreach (IDataRecord rec in records)
{
String country = rec.GetString(rec.GetOrdinal("Name"));
}