Как вернуть MySqlDataReader до закрытия читателя [дубликат]
-
11-12-2019 - |
Вопрос
Хорошо, мой код сейчас:
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;
}
}
}
В другой функции у меня есть:
using(MySqlDataReader readers = _connection.CreateQuery(query, connectString))
В настоящее время в таком виде, когда я возвращаю читателя в читалку, это не имеет никакой ценности.Я прошел и проверил, что на момент возврата читатель имел правильную информацию.Однако у читателей нет ценностей.Я, наверное, упускаю что-то совершенно глупое.Но любая помощь в этом будет оценена по достоинству.Спасибо!
Решение
С помощью команды using ваш код фактически уничтожает соединение и команду до того, как управление будет возвращено вызывающей стороне.По сути, ваш объект соединения и ваш объект команды, созданный в операторах using, удаляются до того, как вызывающий код сможет его использовать, поэтому его больше нельзя использовать.
Вероятно, вы захотите что-то сделать с результатами запроса, а не с самим считывателем.Возможно, загрузить его в таблицу?Что-то вроде:
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;
}
Другие советы
Вместо того, чтобы вернуть Datareader
или скопируйте все записи в память DataTable
что вы возвращаете в целом, вы можете вернуть IEnumerable<IDataRecord>
который является основным интерфейсом DataReader
рекордные орудия.
Так что это должно работать, поскольку yield
вызывает Connection
чтобы остаться в живых:
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;
}
}
}
}
}
Если вы хотите, например, взять только первые 5 записей:
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"));
}