11

設定する必要のある一連のコントロール (ドロップダウン リストなど) を含む ASP.NET ページがあります。

コントロールごとに往復するのではなく、db に 1 回アクセスして複数のレコードセットを取得したいと考えています。

複数のテーブルを DataSet に戻すことも、DataReader を戻し、'.NextResult' を使用して各結果セットをカスタム ビジネス クラスに入れることもできます。

DataReader アプローチを使用すると、十分に大きなパフォーマンス上の利点が得られる可能性がありますか?それとも、DataSet アプローチを使用する必要がありますか?

これを通常どのように処理するかの例をいただければ幸いです。

4

10 に答える 10

7
  1. データベースから取得するレコードが 1000 件を超える場合。
  2. カスタム ストアとカスタム ページングにあまり関心がない場合は、「GridView の場合
  3. サーバーにメモリ ストレスがある場合。
  4. そのページが呼び出されるたびにデータベースに接続するのに問題がない場合。

次に、DataReader を使用する方が良いと思います。

そうしないと

  1. データベースから取得するレコードが 1000 未満の場合。
  2. 保存とページングに興味がある場合は、「GridView の場合
  3. サーバーにメモリ ストレスがない場合。
  4. 一度だけデータベースに接続して、キャッシングのメリットを享受したい場合。

次に、DataSet を使用する方が良いと思います。

私が正しいことを願っています。

于 2009-06-21T11:02:40.760 に答える
4

データは常に、特定の用途のために定義されたクラスに入れます。DataSets または DataReaders を渡さないでください。

于 2008-10-07T20:34:57.863 に答える
4

すでにたくさんの良い答えがあるにもかかわらず、まだ答えがマークされていないのを見て、私も2ビット追加すると思いました.

DataReaders はかなり高速なので、私は DataReaders を使用します (パフォーマンスがあなたのものであるか、できるだけ多くが必要な場合)。私が取り組んできたほとんどのプロジェクトでは、各テーブルに数百万のレコードがあり、パフォーマンスが懸念されます。

DataReader を複数のレイヤーにまたがって送信するのは得策ではないと言う人もいます。「DbDataReader」は技術的にデータベースに関連付けられていない(または関連付ける必要がない)ため、個人的にはこれを問題とは考えていません。つまり、データベースを必要とせずに DbDataReader のインスタンスを作成できます。

これを行う理由は次のとおりです。 (Web アプリケーションで) 頻繁に、Html、Xml、JSON、またはその他のデータ変換を生成しています。では、なぜ DaraReader から POCO オブジェクトに移動して、それを XML または JSON に変換してネットワークに送信するのでしょうか。この種のプロセスでは、通常、3 つの変換とオブジェクトのインスタンス化のブート ロードが必要であり、それらをほぼ瞬時に破棄します。

場合によっては、それでいい場合や仕方がない場合もあります。通常、私のデータ レイヤーは、システム内にあるストアド プロシージャごとに 2 つのメソッドを表示します。1 つは DbDataReader を返し、もう 1 つは DataSet/DataTable を返します。DataSet/DataTable を返すメソッドは、DbDataReader を返すメソッドを呼び出してから、DataTable の "Load" メソッドまたはアダプターを使用してデータセットを埋めます。おそらく、何らかの方法でデータを再利用する必要があるか、別のクエリを起動する必要があり、MARS が有効になっていない限り、DbDataReader を開いて別のクエリを起動することができないため、DataSet が必要になることがあります。

現在、DbDataReader または DataSet/DataTable の使用にはいくつかの問題があります。これは通常、コードの明確さ、コンパイル時のチェックなどです。データリーダーにはラッパー クラスを使用でき、実際には DataReader を IEnumerable で使用できます。本当にクールな能力。したがって、強力なタイピングとコードの可読性が得られるだけでなく、IEnumerable も得られます。

したがって、クラスは次のようになります。

public sealed class BlogItemDrw : BaseDbDataReaderWrapper
{
    public Int64 ItemId { get { return (Int64)DbDataReader[0]; } }
    public Int64 MemberId { get { return (Int64)DbDataReader[1]; } }
    public String ItemTitle { get { return (String)DbDataReader[2]; } }
    public String ItemDesc { get { if (DbDataReader[3] != DBNull.Value) return (String)DbDataReader[3]; else return default(String); } }
    public DateTime ItemPubdate { get { return (DateTime)DbDataReader[4]; } }
    public Int32 ItemCommentCnt { get { return (Int32)DbDataReader[5]; } }
    public Boolean ItemAllowComment { get { return (Boolean)DbDataReader[6]; } }
    public BlogItemDrw()
      :base()
    {
    }

    public BlogItemDrw(DbDataReader dbDataReader)
      :base(dbDataReader)
    {
    }
}

DataReader ラッパー

私はブログ記事 (上記のリンク) でさらに詳しく説明しています。これらおよびその他の DataAccess レイヤー コードのソース コード ジェネレーターを作成する予定です。

DataTable にも同じ手法を使用できます (コード ジェネレーターがコードを生成します) ので、VS.NET がすぐに提供するオーバーヘッドなしで、厳密に型指定された DataTable として扱うことができます。

ラッパー クラスのインスタンスは 1 つしかないことに注意してください。したがって、クラスを破棄するためだけにクラスのインスタンスを何百も作成することはありません。

于 2010-11-19T07:19:49.750 に答える
4

ストアド プロシージャが複数のセットを返す場合は、DataReader.NextResult を使用して次のデータ チャンクに進みます。このようにして、すべてのデータを取得してオブジェクトにロードし、できるだけ早くリーダーを閉じることができます。これは、データを取得する最速の方法です。

于 2008-10-07T22:34:50.883 に答える
3

DataReader を中間オブジェクトにマップし、それらのオブジェクトを使用してコントロールをバインドします。特定の状況では DataSet を使用しても問題ありませんが、「データを取得するだけ」という強い理由がある場合は、ほとんどありません。何をするにしても、DataReader をコントロールに渡してバインドしないでください (それを検討していると言ったわけではありません)。

私の個人的な好みは ORM を使用することですが、データ アクセスを手動で行う場合は、DataSet を使用するよりも DataReaders をオブジェクトにマッピングすることをお勧めします。.NextResult を使用して、データベースに何度もアクセスすることを制限することは諸刃の剣ですが、賢明に選択してください。データベースへの 1 回の呼び出しのみを使用して必要なものを常に正確に取得する proc を作成しようとすると、同じことを繰り返すことに気付くでしょう。アプリケーションが数ページしかない場合は、おそらく問題ありませんが、すぐに制御不能になる可能性があります。個人的には、保守性を最大化するために、オブジェクト タイプごとに 1 つの proc を使用し、データベースに複数回 (オブジェクト タイプごとに 1 回) ヒットしたいと考えています。

于 2008-10-07T20:55:21.553 に答える
2

データベースから取得したレコードを更新または削除することに興味がない場合は、DataReader を使用することをお勧めします。基本的に、DataSet は内部で複数の Datareaders を使用するため、DataReader は優れたパフォーマンス上の利点を提供するはずです。

于 2008-10-07T20:35:43.167 に答える
2

ほとんどすべての状況で、データベースからの読み取りに はDataReadersが最適なソリューションです。DataReaders はs またはs よりも高速で、必要なメモリが少なくて済みます。DataTableDataSet

また、多くの場合、オブジェクト指向モデルが壊れDataSetている状況につながる可能性があります。そのデータを操作する方法を知っているオブジェクトの代わりに、リレーショナル データ/スキーマを渡すことはあまりオブジェクト指向ではありません。

したがって、拡張性、スケーラビリティ、モジュール性、およびパフォーマンス上の理由から、DataReader自分が Real Programmer™ であると考える場合は常に s を使用してください ;)

実際と理論における 2 つの事実と議論については、リンクを確認してください。

于 2008-10-07T22:07:51.047 に答える
2

単一の結果セットをフェッチするか、複数の結果セットをフェッチするかに関係なく、コンセンサスは DataSet の代わりに DataReader を使用するようです。

あなたがすべきかどうかに関して複数の結果セットを気にする必要はありませんが、そうすべきではないというのが賢明ですが、その規則に対する合理的な例外のクラスを思いつくことができます: (厳密に) 関連する結果セットです。アプリ内の数百または数十のページで繰り返されるドロップダウン リストに対して、同じ選択肢のセットを返すクエリを追加したくないのは確かですが、使用頻度の低いいくつかのセットを適切に組み合わせることができます。例として、私は現在、ETL データのバッチの「不一致」のいくつかのセットを表示するページを作成しています。これらのクエリはいずれも他の場所で使用される可能性は低いため、それらを単一の「不一致の取得」sproc としてカプセル化すると便利です。一方で、

于 2010-06-03T13:10:13.900 に答える
1

すべての呼び出しに DataReaders を使用する方法に行きました。特に、ドロップダウン リストやその他の単純なアイテムをロードしている場合に、パフォーマンスが大幅に改善されていることに気付きました。

個人的に複数のドロップダウンがある場合、私は通常、5 つの結果セットを返すストアド プロシージャではなく、データの個々のチャンクをプルして取得します。

于 2008-10-07T20:34:57.273 に答える
0

.NET 2.0 以降で使用できる TableAdapter を調べてください。それらが行うことは、厳密に型指定された DataTable の強度を提供し、DataReader を使用してそれをロードする Fill メソッドをそれにマップできるようにすることです。fill メソッドは、既存のストアド プロシージャ、独自の AdHoc SQL にすることも、ウィザードで AdHod またはストアド プロシージャを生成することもできます。

これは、プロジェクト内で新しい XSD DataSet オブジェクトを開始することで見つけることができます。ルックアップ以外にも使用されるテーブルの場合、挿入/更新/削除メソッドを TableAdapter にマップすることもできます。

于 2008-10-07T22:28:42.597 に答える