为什么我不能将数据库中的所有表读入我的数据集中?
Why can't I read all tables from a database into my DataSet?
我正在尝试将 MS-SQL 数据库的所有表读入数据集,该数据集由一组数据表组成。为此,我编写了这段源代码:
try
{
DbConnection.Open();
sqlCommand = DbConnection.CreateCommand();
sqlCommand.CommandText = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES";
// INFORMATION_SCHEMA.TABLES contains the names of all the tables.
sqlDataReader = sqlCommand.ExecuteReader();
cmb_Table_Names.Items.Clear(); // combobox for keeping table names.
while (sqlDataReader.Read())
{
string tmp_Table_Name = sqlDataReader.GetString(0);
cmb_Table_Names.Items.Add(tmp_Table_Name);
DataTable dt_tmp = new DataTable();
using (var da = new SqlDataAdapter($"SELECT * FROM {tmp_Table_Name}",
DbConnection))
{
da.Fill(dt_tmp); // see "whosebug.com/questions/68919147"
}
dataSet.Tables.Add(dt_tmp);
}
sqlDataReader.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Reading DB failed!!!", MessageBoxButton.OK);
}
我在第 da.Fill(dt_tmp);
行陷入了我的 Exception
。
? ex
在立即数window中的结果是:
{"There is already an open DataReader associated with this Command which must be closed first."}
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146233079
HelpLink: null
InnerException: null
Message: "There is already an open DataReader associated with this Command which must be closed first."
Source: "System.Data"
StackTrace: " at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command)\r\n
at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command)\r\n
at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)\r\n
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)\r\n
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)\r\n
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)\r\n
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)\r\n
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)\r\n
at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)\r\n
at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)\r\n
at Database_Handling.MainWindow.Btn_Read_DB_Click(Object sender, RoutedEventArgs e) in <filename>
TargetSite: {Void ValidateConnectionForExecute(System.Data.SqlClient.SqlCommand)}
这是什么意思(特别是因为我只有一个 SqlDataReader
)?
这是否意味着我需要关闭 SqlAdapter
da
之类的东西? (我已经查过了:没有da.Close()
方法)
这是否意味着我无法启动 SQL 命令,而另一个命令仍在读取? (我想这将是一个主要限制)
...
有人知道吗?
提前致谢
感谢the documentation URL from Olivier Rogier:
,我找到了解决方案
它提到 Fill()
方法 隐含地 使用 DataReader
.
所以我决定删除任何 (Sql)DataReader
对象的嵌套,这导致以下代码:
try
{
DbConnection.Open();
sqlCommand = DbConnection.CreateCommand();
sqlCommand.CommandText = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES";
sqlDataReader = sqlCommand.ExecuteReader();
cmb_Table_Names.Items.Clear();
while (sqlDataReader.Read())
{
cmb_Table_Names.Items.Add(sqlDataReader.GetString(0));
}
sqlDataReader.Close(); // <== close first DataReader
foreach (string tmp_Table in cmb_Table_Names.Items)
{
DataTable dt_tmp = new DataTable();
using (var da = new SqlDataAdapter($"SELECT * FROM [{tmp_Table}]",
DbConnection))
{
da.Fill(dt_tmp); // <== use the second implicit DataReader
}
dataSet.Tables.Add(dt_tmp);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Reading DB failed!!!", MessageBoxButton.OK);
}
我正在尝试将 MS-SQL 数据库的所有表读入数据集,该数据集由一组数据表组成。为此,我编写了这段源代码:
try
{
DbConnection.Open();
sqlCommand = DbConnection.CreateCommand();
sqlCommand.CommandText = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES";
// INFORMATION_SCHEMA.TABLES contains the names of all the tables.
sqlDataReader = sqlCommand.ExecuteReader();
cmb_Table_Names.Items.Clear(); // combobox for keeping table names.
while (sqlDataReader.Read())
{
string tmp_Table_Name = sqlDataReader.GetString(0);
cmb_Table_Names.Items.Add(tmp_Table_Name);
DataTable dt_tmp = new DataTable();
using (var da = new SqlDataAdapter($"SELECT * FROM {tmp_Table_Name}",
DbConnection))
{
da.Fill(dt_tmp); // see "whosebug.com/questions/68919147"
}
dataSet.Tables.Add(dt_tmp);
}
sqlDataReader.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Reading DB failed!!!", MessageBoxButton.OK);
}
我在第 da.Fill(dt_tmp);
行陷入了我的 Exception
。
? ex
在立即数window中的结果是:
{"There is already an open DataReader associated with this Command which must be closed first."}
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146233079
HelpLink: null
InnerException: null
Message: "There is already an open DataReader associated with this Command which must be closed first."
Source: "System.Data"
StackTrace: " at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command)\r\n
at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command)\r\n
at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)\r\n
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)\r\n
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)\r\n
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)\r\n
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)\r\n
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)\r\n
at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)\r\n
at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)\r\n
at Database_Handling.MainWindow.Btn_Read_DB_Click(Object sender, RoutedEventArgs e) in <filename>
TargetSite: {Void ValidateConnectionForExecute(System.Data.SqlClient.SqlCommand)}
这是什么意思(特别是因为我只有一个 SqlDataReader
)?
这是否意味着我需要关闭 SqlAdapter
da
之类的东西? (我已经查过了:没有da.Close()
方法)
这是否意味着我无法启动 SQL 命令,而另一个命令仍在读取? (我想这将是一个主要限制)
...
有人知道吗?
提前致谢
感谢the documentation URL from Olivier Rogier:
,我找到了解决方案
它提到 Fill()
方法 隐含地 使用 DataReader
.
所以我决定删除任何 (Sql)DataReader
对象的嵌套,这导致以下代码:
try
{
DbConnection.Open();
sqlCommand = DbConnection.CreateCommand();
sqlCommand.CommandText = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES";
sqlDataReader = sqlCommand.ExecuteReader();
cmb_Table_Names.Items.Clear();
while (sqlDataReader.Read())
{
cmb_Table_Names.Items.Add(sqlDataReader.GetString(0));
}
sqlDataReader.Close(); // <== close first DataReader
foreach (string tmp_Table in cmb_Table_Names.Items)
{
DataTable dt_tmp = new DataTable();
using (var da = new SqlDataAdapter($"SELECT * FROM [{tmp_Table}]",
DbConnection))
{
da.Fill(dt_tmp); // <== use the second implicit DataReader
}
dataSet.Tables.Add(dt_tmp);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Reading DB failed!!!", MessageBoxButton.OK);
}