6

列が IDataReader に存在するかどうかを確認するための 2 つの一般的な方法を見てきました。

public bool HasColumn(IDataReader reader, string columnName)
{
  try
  {
      reader.getOrdinal(columnName)
      return true;
  }
  catch 
  {
       return false;
  }
}

または:

public bool HasColumn(IDataReader reader, string columnName)
{

    reader.GetSchemaTable()
         .DefaultView.RowFilter = "ColumnName='" + columnName + "'";

    return (reader.GetSchemaTable().DefaultView.Count > 0);
}

個人的には、この理由で例外を使用するのが嫌いなので、2 番目のものを使用しました。

ただし、大規模なデータセットでは、RowFilter が列ごとにテーブル スキャンを実行する必要があり、これは非常に遅くなる可能性があると思います。

考え?

4

3 に答える 3

5

この古い宝石に対する合理的な答えがあると思います。

最初のアプローチを使用すると、はるかに簡単になります。例外を回避したい場合は、フィールド名をキャッシュして、キャッシュで TryGet を実行できます。

public Dictionary<string,int> CacheFields(IDataReader reader)
{

    var cache = new Dictionary<string,int>();
    for (int i = 0; i < reader.FieldCount; i++)
    {
        cache[reader.GetName(i)] = i;
    }
    return cache;
}

このアプローチの利点は、よりシンプルで、より適切に制御できることです。また、大文字と小文字を区別しない比較や仮名を区別しない比較を調べたい場合があることに注意してください。これにより、少し扱いに​​くくなります。

于 2009-07-14T01:05:37.253 に答える
1

HasColumn の使用方法に大きく依存します。1 回か 2 回だけ呼び出していますか、それともループで繰り返し呼び出していますか? 列はそこにある可能性が高いですか、それとも事前に完全に知られていませんか?

行フィルターを設定すると、おそらく毎回テーブル スキャンが実行されます。(また、理論的には、GetSchemaTable() はすべての呼び出しでまったく新しいテーブルを生成できますが、これはさらにコストがかかります。SqlDataReader がこれを行うとは思いませんが、IDataReader レベルではわかりません。)これがそれほど大きな問題であるとは想像できません(数千の列などがある場合を除きます)。

(ただし、少なくとも GetSchemaTable() の結果をメソッド内のローカル var に保存して、特定の IDataReader が再生成する可能性がない場合にどこかにキャッシュしない場合は、2 回連続して呼び出すことを避けます。)

通常の状況下で要求する列が存在することが事前にわかっている場合は、例外メソッドの方が少し受け入れやすいです (列が存在しないのは実際には例外的なケースであるため)。そうでない場合でも、パフォーマンスがわずかに向上する可能性がありますが、繰り返し呼び出す場合を除き、パフォーマンスが本当にそれほど重要かどうかを自問する必要があります。

また、繰り返し呼び出す場合は、次のような別のアプローチを検討する必要があります。たとえば、最初に GetSchemaTable() を呼び出し、テーブルをループして、フィールド名をディクショナリまたは高速用に設計された他の構造にロードします。ルックアップ。

于 2009-01-09T23:22:47.167 に答える
0

パフォーマンスへの影響については心配しません。1000 列のテーブル (巨大なテーブルになります) があったとしても、まだ 1000 行の「テーブル スキャン」しか行っていません。それは些細なことである可能性が高いです。

時期尚早の最適化は、不必要に複雑な実装につながるだけです。最適と思われるバージョンを実装し、パフォーマンスへの影響を測定します。パフォーマンス要件と比較して許容できない場合は、代替案を検討してください。

于 2009-05-21T20:05:20.003 に答える