我通常使用DataSet
因为它非常灵活。最近我被分配了代码优化任务,为了减少对数据库的命中,我在一个程序中更改了两个查询。一个Query返回count
,另一个返回actual data
。也就是说,我的stored procedure
返回两个表。现在,我知道如何使用DataSets
读取两个表,但我需要使用DataReader
读取这两个表。为了寻找,我找到了This。
我按照文章写了这样的代码:
dr = cmd.ExecuteReader();
while (dr.Read())
{
}
if (dr.NextResult()) // this line throws exception
{
while (dr.Read())
{
但是我在dt.NextResult上得到了一个例外。例外是:
Invalid attempt to call NextResult when reader is closed.
我也尝试过Google上面的错误,但仍然无法解决问题。
任何帮助都感激不尽。我需要使用datareader
读取多个表,这可能吗?
答案 0 :(得分:55)
试试这个,因为一旦任务结束,这将关闭连接,数据读取器和命令,这样就不会给datareader关闭异常
同样请检查此if(reader.NextResult())
以检查是否有下一个结果
using (SqlConnection connection = new SqlConnection("connection string here"))
{
using (SqlCommand command = new SqlCommand
("SELECT Column1 FROM Table1; SELECT Column2 FROM Table2", connection))
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
MessageBox.Show(reader.GetString(0), "Table1.Column1");
}
if(reader.NextResult())
{
while (reader.Read())
{
MessageBox.Show(reader.GetString(0), "Table2.Column2");
}
}
}
}
}
答案 1 :(得分:12)
我试图重现这个问题(也是因为我以前没有在阅读器中使用过多个表)。但它按预期工作,因此我假设您已省略相关代码。
这是我的测试代码:
using (var con = new SqlConnection(Properties.Settings.Default.ConnectionString))
{
using (var cmd = new SqlCommand("SELECT TOP 10 * FROM tabData; SELECT TOP 10 * FROM tabDataDetail;", con))
{
int rowCount = 0;
con.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
String object1 = String.Format("Object 1 in Row {0}: '{1}'", ++rowCount, rdr[0]);
}
if (rdr.NextResult())
{
rowCount = 0;
while (rdr.Read())
{
String object1 = String.Format("Object 1 in Row {0}: '{1}'", ++rowCount, rdr[0]);
}
}
}
}
}
答案 2 :(得分:1)
我基于Pranay Rana的回答,因为我喜欢将其保持尽可能小。
string rslt = "";
using (SqlDataReader dr = cmd.ExecuteReader())
{
do
{
while (dr.Read())
{
rslt += $"ReqID: {dr["REQ_NR"]}, Shpr: {dr["SHPR_NR"]}, MultiLoc: {dr["MULTI_LOC"]}\r\n";
}
} while (dr.NextResult());
}