Ошибка "System.InvalidOperationException: "Существует назначенный этой команде Command открытый DataReader, который требуется предварительно закрыть."
Необходимо сделать метод, который заполняет DataSet таблицами из заранее известной базы данных MSSQL.
Количество таблиц может разниться, поэтому используется запрос SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_type = 'BASE TABLE'
Выводит ошибку из заголовка при попытке выполнить метод adapter.Fill(ds, reader.GetString(0));
внутри цикла while.
public static void RefreshDS()
{
ds.Reset();
OpenConnection();
SqlDataReader reader = null;
try
{
SqlCommand cmd = new SqlCommand("SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_type = 'BASE TABLE'", conn);
reader = cmd.ExecuteReader();
while (reader.Read())
{
SqlDataAdapter adapter = new SqlDataAdapter($"select * from {reader.GetString(0)}", conn);
adapter.Fill(ds, reader.GetString(0));
}
}
catch (Exception ex)
{
msg.Error(ex.ToString());
}
finally
{
if (reader.HasRows && !reader.IsClosed)
reader.Close();
CloseConnection();
}
}
Если удалить метод adapter.Fill(ds, reader.GetString(0));
, ошибка выводиться не будет, и цикл будет продолжаться, но тогда теряется весь смысл метода RefreshDS
Буду благодарен за помощь
Ответы (1 шт):
Самое простое, сделать здесь последовательно
public static void RefreshDS()
{
ds.Reset();
OpenConnection();
try
{
List<string> tables = new();
using (SqlCommand cmd = new SqlCommand("SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_type = 'BASE TABLE'", conn))
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
tables.Add(reader.GetString(0));
}
}
foreach (string table in tables)
{
using SqlDataAdapter adapter = new SqlDataAdapter($"SELECT * FROM {table}", conn);
adapter.Fill(ds, table);
}
}
catch (Exception ex)
{
msg.Error(ex.ToString());
}
finally
{
CloseConnection();
}
}
В противном случае следует использовать разные подключения для ридера и адаптера. Ну или включить MARS.