Sütun adlarını bir SqlDataReader'dan alabilir misiniz?


276

Veritabanına bağlandıktan sonra, içinde döndürülen tüm sütunların adını alabilir miyim SqlDataReader?

Yanıtlar:


460
var reader = cmd.ExecuteReader();

var columns = new List<string>();

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

veya

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

71
sütunları yinelemenizi sağlayan numaralandırılamaz bir arayüzün olmaması delilik.
JohnFx

61
Biraz daha kısa:columns = Enumerable.Range(0, reader.FieldCount) .Select(reader.GetName).ToList();
Alex

2
Harika çalışıyor. Ayrıca, sütun adının çevresinde tırnak işaretleri kullanmadığım sürece sütun adlarımın büyük harf olduğunu öğrendim. SELECT id AS "MyId" FROM table;
styfle

efendim, tüm sütun adlarını küçük harfle döndürüyor. Tablodaki sütun adlarının tümü
OBJECTID

2
Dim sütunları () As String = Enumerable.Range (0, cTab.FieldCount). (İşlev (n) cTab.GetName (n)) öğesini seçin. ToArray
swe

77

Sütun dizinini kabul eden ve sütunun adını döndüren bir GetNameişlev vardır SqlDataReader.

Tersine, GetOrdinalbir sütun adı alan ve sütun dizinini döndüren bir vardır.


3
İki neden: Birincisi, orijinal poster henüz bir cevap seçmedi ve ikincisi, sorunun çözümü hakkında daha ayrıntılı bir açıklama veren, daha sonra sadece işlevselliğin varlığını gösteren başka cevaplar da var. Şahsen, Steven Lyons'ın GetName hakkında konuşmakla kalmayıp aynı zamanda FieldType ve DataType'a da girdiği gibi en iyi yanıtı seviyorum.
Stephen Wrighton

1
GetOrdinalmükemmeldi. Sorunum için GetNameçok daha temiz bir çözüm arıyordum GetOrdinal.
goodeye

43

Sütun adlarını bir DataReader'dan alabilirsiniz.

İşte önemli kısmı:

  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

Daha önce bahsedildi. Sadece bir LINQ cevabı:

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();

İkincisi daha temiz ve çok daha hızlı. GetSchemaTableİlk yaklaşımda önbelleğe alsanız bile , sorgulama çok yavaş olacaktır.


Bunu Değerler ile yapmanın bir yolu var mı?
Travis Heeter

@TravisHeeter Seni anlamadım. Neyin değerlerinden sütun adları bulun?
nawfal

Sonuçtaki değerleri bir listeye veya belki de her şeyi IEnumerable <dinamik> bir nesneye almanın doğu yoludur.
Travis Heeter

@TravisHeeter evet yapabilirdi reader.Cast<IDataRecord>().ToList(). dynamicOrada anahtar kelime kullanabilirsiniz IDataRecordama hiçbir faydası ile inanıyorum . DataTablebir seferde yüklemeyi kolaylaştırmak için tasarlanmıştır, bu yüzden bunu da kullanabilirsiniz, ancak istek üzerine yükleme avantajını kaybedersiniz (veri okuyucu ile herhangi bir noktada yüklemeyi durdurabilirsiniz) var dt = new DataTable(); dt.Load(reader); return dt.AsEnumerable().ToList();. Bunu sizin için otomatikleştirebilecek birçok kitaplık var, onları burada bulabilirsiniz stackoverflow.com/questions/11988441 ve burada stackoverflow.com/questions/1464883
nawfal

Denedim reader.Cast<IEnumerable<dynamic>>ve .Cast<dynamic>der ki, Cannot convert method group 'Cast' to non-delegate type 'dynamic'. Did you intend to invoke the method?orada neyi yanlış yaptım? (Kaynaklarınıza baktım, ama bilmediğim sütun adını bilmenizi
istediler

6

Yalnızca sütun adlarını istiyorsanız, şunları yapabilirsiniz:

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"));
    }
}

Ama sadece bir sıraya ihtiyacınız varsa, AdoHelper eklememi seviyorum. Tek satırlık bir sorgunuz varsa ve kodunuzdaki veri tablosuyla uğraşmak istemiyorsanız, bu ekleme harika. Sütun adlarının ve değerlerinin büyük / küçük harfe duyarlı olmayan bir sözlüğünü döndürüyor.

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;en kötü uygulamadır.
asawyer

2
bu sadece bir örnek
Yakir Manor

5
Asawyer, en azından nedenini söylemelisin. Sanırım "fırlatma" yı kullanman gerektiğini söyleyeceksin. bunun yerine orijinal strack izleme detaylarını kaybetmezsiniz.
Brent Rittenhouse


3

Bir uzantı yöntemi kullanın:

    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

Emin olabilirsin.


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(" ");
  }

}

Bu aslında: http://www.dotnetjunkies.ddj.com/Article/B82A22D1-8437-4C7A-B6AA-C6C9BE9DB8A6.dcik


1

SQL'de başarmak daha kolaydır

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();
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.