104

私の質問はSqlDataReader、C# を使用してクエリによって返される行数を取得する方法です。Read()これについていくつかの回答を見てきましたが、メソッドでwhileループを実行してカウンターをインクリメントすることを述べているものを除いて、明確に定義されたものはありませんでした。

私の問題は、最初の行が列ヘッダー名であり、その後のすべての行が行データになるように多次元配列を埋めようとしていることです。

List コントロールにデータをダンプするだけでよいことはわかっていますが、それについて心配する必要はありませんが、自分自身の教育のために、さまざまな形式で選択して表示するときに、配列にデータを出し入れしたいと考えています。

したがって、行の量と列データを取得するには、開いてから再度開くRead()必要があるため、++の方法を実行してからインクリメントすることはできないと思います。Read()Read()

私が話していることのほんの一例です:

int counter = 0;    

while (sqlRead.Read())
{
    //get rows
    counter++
}

次に、列を通過してポップする for ループ

something.Read();

int dbFields = sqlRead.FieldCount;

for (int i = 0; i < dbFields; i++)
{
   // do stuff to array
}
4

6 に答える 6

102

次の 2 つのオプションしかありません。

  • すべての行を読み取って調べます(その後、それらを保存することもできます)

  • 特殊な SELECT COUNT(*) クエリを事前に実行します。

DataReader ループを 2 回実行すると非常にコストがかかるため、クエリを再実行する必要があります。

そして (Pete OHanlon のおかげで) 2 番目のオプションは、スナップショット分離レベルでトランザクションを使用する場合にのみ同時実行セーフです。

とにかくすべての行をメモリに保存したいので、唯一の賢明なオプションは、すべての行を柔軟なストレージ (List<>またはDataTable) に読み取ってから、データを任意の形式にコピーすることです。インメモリ操作は常にはるかに効率的です。

于 2009-09-05T13:25:53.740 に答える
8

上記のように、データセットまたは型指定されたデータセットは、フィルタリングを行うために使用できる優れた一時構造である可能性があります。SqlDataReader は、データを非常に迅速に読み取るためのものです。while() ループにいる間は、まだ DB に接続されており、次に進む前に次の結果を読み取り/処理するために何をするかを待っています。この場合、すべてのデータを取得し、DB への接続を閉じて、結果を「オフライン」で処理すると、パフォーマンスが向上する可能性があります。

人々はデータセットを嫌っているように見えるので、上記は厳密に型指定されたオブジェクトのコレクションでも実行できます。

于 2009-09-05T13:39:27.583 に答える
7

データ リーダーから直接行数を取得することはできません。これは、ファイアホース カーソルと呼ばれるものであるためです。つまり、データは、実行中の読み取りに基づいて行単位で読み取られます。2回の読み取りの間にデータが変更され、異なる結果が得られる可能性があるため、データに対して2回の読み取りを行うことはお勧めしません。

あなたができることは、データを一時的な構造に読み込み、それを 2 番目の読み取りの代わりに使用することです。または、データを取得するメカニズムを変更し、代わりに DataTable などを使用する必要があります。

于 2009-09-05T13:28:44.670 に答える
1

また、上位の結果を返す必要があるが、クエリに一致する合計行を取得したいという状況にも直面しています。私はついにこの解決策にたどり着きました:

   public string Format(SelectQuery selectQuery)
    {
      string result;

      if (string.IsNullOrWhiteSpace(selectQuery.WherePart))
      {
        result = string.Format(
@"
declare @maxResult  int;
set @maxResult = {0};

WITH Total AS
(
SELECT count(*) as [Count] FROM {2}
)
SELECT top (@maxResult) Total.[Count], {1} FROM Total, {2}", m_limit.To, selectQuery.SelectPart, selectQuery.FromPart);
      }
      else
      {
        result = string.Format(
@"
declare @maxResult  int;
set @maxResult = {0};

WITH Total AS
(
SELECT count(*) as [Count] FROM {2} WHERE {3}
)
SELECT top (@maxResult) Total.[Count], {1} FROM Total, {2} WHERE {3}", m_limit.To, selectQuery.SelectPart, selectQuery.FromPart, selectQuery.WherePart);
      }

      if (!string.IsNullOrWhiteSpace(selectQuery.OrderPart))
        result = string.Format("{0} ORDER BY {1}", result, selectQuery.OrderPart);

      return result;
    }
于 2016-01-15T13:51:51.337 に答える