Como devolver um MySqlDataReader antes que o leitor está fechado [duplicado]
-
11-12-2019 - |
Pergunta
Ok, meu código é atualmente:
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;
}
}
}
Em função de outra, eu tenho:
using(MySqlDataReader readers = _connection.CreateQuery(query, connectString))
Atualmente, desta forma, quando eu voltar leitor para uma leitores, não há nenhum valor.Eu já concluído, e verificado que o ponto de retorno, o leitor teve a correta informação.Ainda assim, os leitores que não tem nenhum valor.Eu provavelmente estou faltando alguma coisa completamente idiota.Mas toda e qualquer ajuda neste serão apreciados.Obrigado!
Solução
Com o comando, o código está realmente indo para descartar a ligação e o comando antes que o controle é retornado ao chamador.Essencialmente, o objecto de ligação e o objeto de comando criado usando instruções são eliminados antes de o código de chamada é capaz de usá-lo mais utilizável.
Você provavelmente quer fazer algo com os resultados da consulta, ao invés de incluir o leitor de si mesmo.Talvez carregá-lo em uma tabela?Algo como:
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;
}
Outras dicas
Em vez de devolver o Datareader
ou copiar todos os registos para uma memória DataTable
que você retornar como um todo, você pode retornar um IEnumerable<IDataRecord>
o que é a interface básica de um DataReader
registro implementa.
Então, isso deve funcionar desde o yield
faz com que o Connection
para manter viva a:
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 você quiser, por exemplo, tirar apenas os 5 primeiros registros:
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"));
}