Как вернуть MySqlDataReader до закрытия читателя [дубликат]

StackOverflow https://stackoverflow.com//questions/11658084

  •  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"));
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top