2

「SELECT name, city, country FROM People」というクエリを呼び出しているとします。SqlDataReader を実行すると、SQL クエリと同じ順序で列が表示されますか?

つまり、次のコードが常に正しく機能することを信頼できますか。

SqlConnection connection = new SqlConnection(MyConnectionString);
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = "SELECT [name], [city], [country] WHERE [id] = @id";

try
{
    connection.Open();
    SqlDataReader reader = command.ExecuteReader(System.Data.CommandBehavior.SingleRow);

    if (reader.Read())
    {
        // Read values.
        name = reader[0].ToString();
        city = reader[1].ToString();
        country = reader[2].ToString();
    }
}
catch (Exception)
{
    throw;
}
finally
{
    connection.Close();
}

また、序数 (reader["name"]) の代わりに列名を使用すると、どの程度のパフォーマンスが失われますか?

SqlDataReader での列の順序付けの動作を説明している公式の Microsoft ドキュメントはありますか?

4

3 に答える 3

5

はい、そうですが、SqlDataReader.GetName(ordinal) と SqlDataReader.GetOrdinal(name) も使用できます。

パフォーマンスに関しては、次の行のデータを取得するなどのオーバーヘッドと比較すると、おそらく非常に重要ではないと思います。

于 2009-05-28T04:50:19.457 に答える
5

Josh に完全に同意します。フィールドの位置は、SQL クエリ テキストで指定したとおりです。

しかし、より堅牢であるため、列名を使用することをお勧めします。たとえば、SQL クエリにフィールドを追加する必要がある場合はどうでしょうか。

command.CommandText = "SELECT [name], [jobtitle], [city], [country] WHERE [id] = @id";

ここで突然、すべてのコードを書き直して位置を変更する必要があります....

データ リーダーによって返されたすべての行を列挙するループの外側で通常行うことは、関心のある各フィールドの位置を決定することです。

int namePosition = reader.GetOrdinal("name");
int cityPosition = reader.GetOrdinal("city");

次に、データを処理するループ内でこれらの位置を使用して、個々のフィールドにすばやくアクセスします。そうすれば、位置を一度だけ決定できますが、データのループで位置を使用しています。:-)

マルク

于 2009-05-28T05:09:45.733 に答える
4

この例は、最も保守しやすく、読みやすいものです。

int? quantity = reader.Get<int?>("Quantity");
Guid token = reader.Get<Guid>("Token");

私が作成した次の拡張メソッドに依存しています。DB null チェックを実行し、フィールドが見つからない場合に有益なエラー メッセージを提供し、列が再配置されても中断しません。

internal static T Get<T>(this SqlDataReader reader, string fieldName)
{
    int ordinal;
    try
    {
        ordinal = reader.GetOrdinal(fieldName);
    }
    catch (IndexOutOfRangeException)
    {
        throw new IndexOutOfRangeException(string.Format("Field name '{0}' not found.", fieldName));
    }

    return !reader.IsDBNull(ordinal) ? (T)reader.GetValue(ordinal) : default(T);
}
于 2010-07-20T22:33:11.200 に答える