SqlDataReaderから列名を取得できますか?


回答:


460
var reader = cmd.ExecuteReader();

var columns = new List<string>();

for(int i=0;i<reader.FieldCount;i++)
{
   columns.Add(reader.GetName(i));
}

または

var columns = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList();

71
列を反復処理できる列挙可能なインターフェイスがないのは異常です。
JohnFx

61
少し短い:columns = Enumerable.Range(0, reader.FieldCount) .Select(reader.GetName).ToList();
Alex

2
これはうまくいきます。また、列名を引用符で囲まない限り、列名はすべて大文字であることがわかりました。SELECT id AS "MyId" FROM table;
スタイフル2013

すべての列名を小文字で返します。テーブルの列名はすべてOBJECTIDのように大文字で、リーダーはobjectidのように小文字を返します
Muneem Habib '17 / 11/17

2
そのDim columns()As String = Enumerable.Range(0、cTab.FieldCount).Select(Function(n)cTab.GetName(n))。ToArray
swe

77

列インデックスを受け入れ、列の名前を返すGetName関数がにありSqlDataReaderます。

GetOrdinalに、列名を受け取って列インデックスを返すがあります。


3
2つの理由:1つ目は、元の投稿者がまだ回答を選択していないこと、2つ目は、問題の「解決策」を詳しく説明する他の回答があり、次に機能が存在することだけです。個人的には、GetNameについて話すだけでなく、FieldTypeとDataTypeにも入るので、Steven Lyonsの答えが一番好きです。
スティーブンライトン2013年

1
GetOrdinal完璧だった。私はを探していましたがGetName、に関する私の問題に対するはるかに明確な解決策がありましたGetOrdinal
goodeye 2015

43

DataReaderから列名を取得できます。

ここに重要な部分があります:

  for (int col = 0; col < SqlReader.FieldCount; col++)
  {
    Console.Write(SqlReader.GetName(col).ToString());         // Gets the column name
    Console.Write(SqlReader.GetFieldType(col).ToString());    // Gets the column type
    Console.Write(SqlReader.GetDataTypeName(col).ToString()); // Gets the column database type
  }

15

すでに述べた。ちょうどLINQの答え:

var columns = reader.GetSchemaTable().Rows
                                     .Cast<DataRow>()
                                     .Select(r => (string)r["ColumnName"])
                                     .ToList();

//Or

var columns = Enumerable.Range(0, reader.FieldCount)
                        .Select(reader.GetName)
                        .ToList();

2つ目はよりクリーンで高速です。GetSchemaTable最初のアプローチでキャッシュしたとしても、クエリは非常に遅くなります。


値でこれを行う方法はありますか?
Travis Heeter 2015

@TravisHeeter私はあなたを取得しません。何の値から列名を見つけるか?
nawfal 2015

結果セットの値をリストに取得する東の方法、またはおそらくすべてをIEnumerable <dynamic>オブジェクトに取得することを意味します。
Travis Heeter、2015

@TravisHeeterはい、できますreader.Cast<IDataRecord>().ToList()dynamic代わりにキーワードを使用できますIDataRecordが、メリットはありません。DataTableは、1回限りの読み込みを容易にするように設計されているため、それを使用することもできますが、オンデマンドで読み込むことの利点は失われます(データリーダーを使用すると、いつでも読み込みを停止できます)var dt = new DataTable(); dt.Load(reader); return dt.AsEnumerable().ToList();。あなたのためにこれを自動化することができ、多くのライブラリが見つけ、存在するそれらここstackoverflow.com/questions/11988441、ここstackoverflow.com/questions/1464883
nawfal

私が試したreader.Cast<IEnumerable<dynamic>>.Cast<dynamic>、それは言うCannot convert method group 'Cast' to non-delegate type 'dynamic'. Did you intend to invoke the method?私が間違って何をしましたか?(私はあなたの情報源を見ましたが、彼らはあなたにカラム名を知るように要求しましたが、それは私には
わかり

6

列名のみが必要な場合は、次のようにすることができます。

List<string> columns = new List<string>();
using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly))
{
    DataTable dt = reader.GetSchemaTable();
    foreach (DataRow row in dt.Rows)
    {
        columns.Add(row.Field<String>("ColumnName"));
    }
}

しかし、行が1つだけ必要な場合は、AdoHelperの追加が好きです。この追加は、1行のクエリがあり、コードでデータテーブルを処理したくない場合に最適です。列名と値の大文字と小文字を区別しない辞書を返します。

public static Dictionary<string, string> ExecuteCaseInsensitiveDictionary(string query, string connectionString, Dictionary<string, string> queryParams = null)
{
    Dictionary<string, string> CaseInsensitiveDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
    try
    {
        using (SqlConnection conn = new SqlConnection(connectionString))
        {
            conn.Open();
            using (SqlCommand cmd = new SqlCommand())
            {
                cmd.Connection = conn;
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = query;

                // Add the parameters for the SelectCommand.
                if (queryParams != null)
                    foreach (var param in queryParams)
                        cmd.Parameters.AddWithValue(param.Key, param.Value);

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    DataTable dt = new DataTable();
                    dt.Load(reader);
                    foreach (DataRow row in dt.Rows)
                    {
                        foreach (DataColumn column in dt.Columns)
                        {
                            CaseInsensitiveDictionary.Add(column.ColumnName, row[column].ToString());
                        }
                    }
                }
            }
            conn.Close();
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
    return CaseInsensitiveDictionary;
}

1
throw ex;最悪の習慣です。
asawyer

2
その一例
Yakir Manor

5
Asawyer、少なくとも理由を言うべきです。「スロー」を使うべきだと言うつもりだと思います。代わりに、元の追跡トレースの詳細が失われないようにします。
ブレントリッテンハウス


3

拡張メソッドを使用します。

    public static List<string> ColumnList(this IDataReader dataReader)
    {
        var columns = new List<string>();
        for (int i = 0; i < dataReader.FieldCount; i++)
        {
            columns.Add(dataReader.GetName(i));
        }
        return columns;
    }

2

できますよ。


protected void GetColumNames_DataReader()
{
  System.Data.SqlClient.SqlConnection SqlCon = new System.Data.SqlClient.SqlConnection("server=localhost;database=northwind;trusted_connection=true");
  System.Data.SqlClient.SqlCommand SqlCmd = new System.Data.SqlClient.SqlCommand("SELECT * FROM Products", SqlCon);

  SqlCon.Open();

  System.Data.SqlClient.SqlDataReader SqlReader = SqlCmd.ExecuteReader();
  System.Int32 _columncount = SqlReader.FieldCount;

  System.Web.HttpContext.Current.Response.Write("SqlDataReader Columns");
  System.Web.HttpContext.Current.Response.Write(" ");

  for ( System.Int32 iCol = 0; iCol < _columncount; iCol ++ )
  {
    System.Web.HttpContext.Current.Response.Write("Column " + iCol.ToString() + ": ");
    System.Web.HttpContext.Current.Response.Write(SqlReader.GetName( iCol ).ToString());
    System.Web.HttpContext.Current.Response.Write(" ");
  }

}

これはもともと:http : //www.dotnetjunkies.ddj.com/Article/B82A22D1-8437-4C7A-B6AA-C6C9BE9DB8A6.dcik


1

SQLでそれを達成する方が簡単です

var columnsList = dbContext.Database.SqlQuery<string>("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'SCHEMA_OF_YOUE_TABLE' AND TABLE_NAME = 'YOUR_TABLE_NAME'").ToList();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.