53

我通常使用DataSet它,因为它非常灵活。最近我被分配了代码优化任务,为了减少对数据库的命中,我在一个过程中更改了两个查询。一个查询返回count,另一个返回actual data。也就是说,Mystored 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.

我也搜索了上面的错误,但仍然无法解决问题。任何帮助都感激不尽。我需要使用 读取多个表datareader,这可能吗?

4

4 回答 4

66

试试这个,因为一旦任务结束,这将关闭连接、数据读取器和命令,这样就不会给数据读取器关闭异常

也请像这样检查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");
              }
            }
        }
    }
}
于 2012-10-19T07:27:12.983 回答
13

我试图重现这个问题(也因为我之前没有在阅读器中使用过多个表)。但它按预期工作,因此我假设您已经省略了相关代码。

这是我的测试代码:

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]);
                }
            }
        }
    }
}
于 2012-10-19T07:39:19.837 回答
2

我建立在 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());
}
于 2019-08-26T17:10:15.227 回答
1

这个问题很老,但我发现答案不正确。这是我的做法:

        List<DataTable> dataTables = new();
        using IDataReader dataReader = command.ExecuteReader();
        do
        {
            DataTable dataTable = new();
            dataTable.Load(dataReader);
            dataTables.Add(dataTable);
        }
        while (!dataReader.IsClosed);
于 2021-08-24T16:25:29.397 回答