2009-03-25 5 views

Antwort

336
var reader = cmd.ExecuteReader(); 

var columns = new List<string>(); 

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

oder

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

Es ist verrückt, dass es keine aufzählbare Schnittstelle gibt, mit der Sie durch die Spalten iterieren können. – JohnFx

+48

Etwas kürzer: 'columns = Enumerable.Range (0, reader.FieldCount) \t \t .Wählen Sie (reader.GetName) .ToList();' – Alex

+2

Das funktioniert großartig.Ich fand auch heraus, dass meine Spaltennamen in Großbuchstaben geschrieben waren, es sei denn, ich verwendete den Namen der Spalte in Anführungszeichen. 'SELECT ID AS" MyId "FROM Tabelle;' – styfle

69

Es gibt eine GetName Funktion auf der SqlDataReader, die den Spaltenindex akzeptiert und den Namen der Spalte zurückgibt.

Umgekehrt gibt es eine GetOrdinal, die einen Spaltennamen übernimmt und den Spaltenindex zurückgibt.

+5

Warum in aller Welt zu erreichen, ist dies nicht als Antwort markiert? –

+3

Zwei Gründe: Erstens hat das ursprüngliche Poster noch keine Antwort gewählt, und zweitens gibt es andere Antworten, die eine detailliertere Beschreibung der "Lösung" des Problems geben, als nur die Existenz der Funktionalität. Persönlich mag ich die Antwort von Steven Lyons am besten, da es nicht nur über GetName spricht, sondern auch über FieldType und DataType. –

+0

'GetOrdinal' war perfekt. Ich suchte nach "GetName", aber viel sauberere Lösung für mein Problem mit "GetOrdinal". – goodeye

33

Sie können die Spaltennamen von einem DataReader abrufen.

Hier ist der wichtige Teil:

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 
    } 
+1

Der Link ist tot. – shuttle87

3

Sicher können.


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

} 

Dies ist ursprünglich aus: http://www.dotnetjunkies.ddj.com/Article/B82A22D1-8437-4C7A-B6AA-C6C9BE9DB8A6.dcik

2

Ich verwende die GetSchemaTable Methode, die über die Schnittstelle IDataReader ausgesetzt ist.

+0

ja hier ist ein Artikel darüber: Abrufen von Schema-Informationen aus dem Datenreader https://msdn.microsoft.com/en-us/library/haa3afyz(v=vs.110).aspx –

6

Wenn Sie die Spaltennamen nur wollen, können Sie tun:

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

Aber wenn Sie nur eine Zeile benötigen, Ich mag meinen AdoHelper hinaus. Dieser Zusatz ist großartig, wenn Sie eine einzelne Zeilenabfrage haben und Sie nicht mit der Datentabelle in Ihrem Code arbeiten wollen. Es gibt ein case-insensitive Wörterbuch von Spaltennamen und -werten zurück.

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

'werfen Sie ex;' ist eine ungünstigste Praxis. – asawyer

+1

es ist nur ein Beispiel –

+1

Asawyer, sollten Sie zumindest sagen, warum. Ich nehme an, du wirst sagen, du solltest "werfen" benutzen; stattdessen, damit Sie nicht die ursprünglichen Spurspurdetails verlieren. –

12

Bereits erwähnt. Nur eine LINQ Antwort:

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

Das zweite ist sauberer und viel schneller. Selbst wenn Sie GetSchemaTable im ersten Ansatz zwischenspeichern, wird die Abfrage sehr langsam sein.

+0

Gibt es eine Möglichkeit, dies mit Werten zu tun? –

+0

@TravisHeeter Ich verstehe dich nicht. Finde Spaltennamen von Werten von was? – nawfal

+0

Ich meine nur ein Ost-Weg, um die Werte in der Ergebnismenge in eine Liste oder vielleicht die ganze Sache zu einem IEnumerable Objekt zu bekommen. –

3

eine Erweiterungsmethode verwenden:

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; 
    } 
1

Es ist einfacher, es in 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(); 
Verwandte Themen