49

IndexOutOfRangeException をチェックするだけでなく、IDataReader ベースのオブジェクトにフィールドが存在するかどうかを確認する方法はありますか?

要するに、IDataReader ベースのオブジェクトを受け取り、厳密に型指定されたレコードのリストを作成するメソッドがあります。1 つの例では、1 つのデータ リーダーが、他のデータ リーダーにはないフィールドを持っています。必要がなければ、このメソッドにフィードするすべてのクエリを書き直して、このフィールドの何らかの形式を含めることは本当にしたくありません。これまでのところ、それを行う方法を理解できた唯一の方法は、以下に示すように、1 つの一意のフィールドを try/catch ブロックにスローすることです。

try
{
    tmp.OptionalField = reader["optionalfield"].ToString();
}
catch (IndexOutOfRangeException ex)
{
    //do nothing
}

「オプション フィールド」を他のクエリに追加したり、ローディング メソッドをコピーして、一方のバージョンではオプション フィールドを使用し、もう一方のバージョンでは使用しないようにする以外に、よりクリーンな方法はありますか?

私も2.0フレームワークにいます。

4

7 に答える 7

64

メソッドを使用して解決策を見つけることになりましたreader.GetName(int)。ロジックを網羅するために、以下のメソッドを作成しました。

public bool ColumnExists(IDataReader reader, string columnName)
{
    for (int i = 0; i < reader.FieldCount; i++)
    {
         if (reader.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
        {
            return true;
        }
    }

    return false;
}
于 2009-07-31T16:03:00.763 に答える
21

以下は、データ リーダーが与えられた列名文字列のリストです。(結果は最後に読んだものに基づいているため、読者が何を読んだかによっては同じではない可能性があることに注意してください)。

var cols = reader.GetSchemaTable()
                 .Rows
                 .OfType<DataRow>()
                 .Select(row => row["ColumnName"]);

または、列が存在するかどうかを確認するには:

public bool ColumnExists(IDataReader reader, string columnName)
{

  return reader.GetSchemaTable()
               .Rows
               .OfType<DataRow>()
               .Any(row => row["ColumnName"].ToString() == columnName);
}
于 2012-07-12T21:48:53.463 に答える
7

これはうまくいくはずです、これを試してください:

private static bool ColumnExists(SqlDataReader reader, string columnName)
        {
            using (var schemaTable = reader.GetSchemaTable())
            {
                if (schemaTable != null)
                    schemaTable.DefaultView.RowFilter = String.Format("ColumnName= '{0}'", columnName);

                return schemaTable != null && (schemaTable.DefaultView.Count > 0);
            }
        }
于 2011-10-13T09:56:52.320 に答える
6

正直に立っているようです。あなたの実際の列名がそこにあることは知っていますが、私は間違った道を進んでいました。このリファレンスは、物事を少し明確にするのに役立ちましたが、それを行うためのエレガントな方法があるかどうかはまだわかりません。上記のリンクから適応すると、次のようにすべての列のリストを取得できます。

List<string> myCols = new List<string>();
DataTable schema = reader.GetSchemaTable();
foreach (DataRow row in schema.Rows)
{
    myCols.Add(row[schema.Columns["ColumnName"]]);
}

残念ながら、schema.Rowsにはインデックスでしかアクセスできないようです。そのため、名前で確認する前に、最初に行をループすることを回避できるかどうかはわかりません。その場合、元のソリューションははるかにエレガントに見えます!

注:私の最初の回答では、reader.GetSchemaTable()。Columns["optionalfield"]によって列の存在を確認することを提案しました。

于 2009-07-30T13:30:53.547 に答える
1

Don't need so much complication, just this:

bool bFieldExists = datareader.GetSchemaTable().Columns.Contains(strFieldName);
于 2009-09-02T12:45:20.897 に答える