2012-02-21 18 views
1

SqlDataReaderを使用して結果を処理するヘルパー関数をいくつか書いています。SqlDataReaderでread()が呼び出されているか確認してください。

while(reader.read()){ 
    // Read fields 
} 

をしかし、私は機能すでに行上に配置されている読者を渡すことが私の、この場合には、私はそれが現在の行を処理したい:今、通常あなたはそうのようなループを構築したいです。上記のコードは、関数を呼び出す前にread()が呼び出されていない場合にのみ、結果セット全体を出力します。私は、関数はこのような何かやりたい

if(!reader._dataReady) 
    rowExists = reader.read() // Read 
while(rowExists){ 
    // read fields 
    rowExists = reader.read() 
} 

_dataReadyは、しかし、それはプライベートだ、SqlDataReaderの実際のメンバーであり、私が必要なものをやっているようです!読者が実際の行に配置されているかどうかを判断する方法があります。フィールドを読み込み、例外をキャッチしようとしていません。

+0

あなたのヘルパーに電話する前に必ず読書をするように強制することはできませんか?そうしなければ、あなたは捕まえることができ、包み込み、そして転覆することができる例外につながるでしょう。あなたのターゲットオーディエンスは明らかに開発者なので、あなたのAPIに従うように強制します。 –

答えて

2

なぜSqlDataReaderをサブクラス化せず、Read()メソッドを作成するだけですか?私はすべてのプロジェクトでそれを持っています:

public class SafeDataReader : IDataReader, SqlDataReader 
{ 
    public IDataReader reader {get;set;} 
    public int GetInt32(string aFieldName, int aDefault); 
    public int? GetInt32Nullable(string aFieldName); 
    .... 
} 
+0

良いアイデア。私は、読者の位置を追跡する列挙型を格納することができました:SafeDataReaderPosition.BeforeRows - SafeDataReaderPosition.OnRow - SafeDataReaderPosition.EndOfFile。 データセットを使用して非同期パフォーマンスを犠牲にすることなく、すべて。なぜこれが実装の一部ではないのか分かりません... – Trent

0

FieldCountプロパティを使用できます。 the documentationによると、有効なレコードセットに配置されていない場合はゼロを返します。

いくつかの他のソリューション:

  1. は、あなたのRead()を行い、あなたのヘルパーメソッドの外に完全にループ(と常に現在行だけで動作する)

  2. ですか、あなたのRead()ヘルパー内に完全にをループメソッドを呼び出して、先に進んでいない新鮮なデータリーダーに常に渡します。

  3. 初めての場合Read()がデータリーダーの外部にある場合は、ヘルパーメソッド内でループを続行してください。常にデータリーダーが最初のレコードに進んだとします。

  4. おそらく、過剰スキル:すべての呼び出しを(おそらくコンストラクタを介して渡された)基底のデータリーダーに転送するIDataReaderのラッピング実装を記述しますが、Readが呼び出されたかどうかを示すプロパティを公開します。

+0

read()がまだ呼び出されていない場合、fieldCountプロパティはゼロを返しません。 SQLが結果セットをまったく返さなかった場合にのみ、ゼロを返します。 – Trent

+0

明確にする:Trentは正しいです - もし読み込みが行われていて、 'Read()'が呼び出されておらず、読み手がフィールドを持つ行を持っているなら、 'FieldCount'は結果セットのフィールドの数に設定されます。 – mcw0933

0

それは目的を過負荷の一種ですが、次のように動作するはずです:

rowExists = reader.FieldCount > 0; 

私はあなた自身があなたがリードを(やっている設計に問題が発見しようとしていると思われます)■コード内の別の場所に配置します。メソッド内でデータ操作のみを行い(IDataReaderの代わりにIDataRecordとして渡す)、レコードトラバーサルロジックを呼び出し元のままにしてください。

関連する問題