¿Puedes obtener los nombres de las columnas de un SqlDataReader?

Resuelto Blankman asked hace 15 años • 12 respuestas

Después de conectarme a la base de datos, ¿puedo obtener el nombre de todas las columnas que se devolvieron en mi SqlDataReader?

Blankman avatar Mar 25 '09 20:03 Blankman
Aceptado
var reader = cmd.ExecuteReader();

var columns = new List<string>();

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

o

var columns = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList();
Rob Stevenson-Leggett avatar Mar 25 '2009 13:03 Rob Stevenson-Leggett

Hay una GetNamefunción que SqlDataReaderacepta el índice de la columna y devuelve el nombre de la columna.

Por el contrario, hay un GetOrdinalque toma el nombre de una columna y devuelve el índice de la columna.

Stephen Wrighton avatar Mar 25 '2009 13:03 Stephen Wrighton

Puede obtener los nombres de las columnas de un DataReader.

Aquí está la parte importante:

  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
  }
Steven Lyons avatar Mar 25 '2009 13:03 Steven Lyons

Ya mencionado. Sólo una respuesta 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();

El segundo es más limpio y mucho más rápido. Incluso si almacena en caché GetSchemaTableen el primer enfoque, la consulta será muy lenta.

nawfal avatar Dec 12 '2013 14:12 nawfal

Si solo desea los nombres de las columnas, puede hacer:

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

Pero si solo necesitas una fila, me gusta mi adición de AdoHelper. Esta adición es excelente si tiene una consulta de una sola línea y no desea lidiar con la tabla de datos en su código. Está devolviendo un diccionario que no distingue entre mayúsculas y minúsculas de nombres y valores de columnas.

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;
}
Yakir Manor avatar Aug 29 '2013 16:08 Yakir Manor