53

DataSet伸縮性に優れているので普段使いしています。最近、コード最適化タスクが割り当てられました。データベースへのヒットを減らすために、プロシージャ内の 2 つのクエリを変更しています。1 つのクエリは を返し、もう 1 つのクエリはcountを返しますactual data。つまり、Mystored procedureは 2 つのテーブルを返します。これで、 を使用して両方のテーブルを読み取る方法がわかりましたが、 を使用してDataSets両方のテーブルを読み取る必要がありますDataReader。それを求めて、私はこれを見つけました。

私は記事に従い、次のようにコードを書きました。

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 に答える
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 に答える