Respuestas:
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();
columns = Enumerable.Range(0, reader.FieldCount) .Select(reader.GetName).ToList();
SELECT id AS "MyId" FROM table;
Hay una GetName
función en la SqlDataReader
que acepta el índice de columna y devuelve el nombre de la columna.
Por el contrario, hay una GetOrdinal
que toma el nombre de una columna y devuelve el índice de la columna.
GetOrdinal
fue perfecto. Estaba buscando GetName
, pero una solución mucho más limpia para mi problema con GetOrdinal
.
Puede obtener los nombres de columna 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
}
Ya mencionado. Solo 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 GetSchemaTable
en caché en el primer enfoque, la consulta será muy lenta.
reader.Cast<IDataRecord>().ToList()
. Creo que podría usar dynamic
palabras clave allí en lugar de hacerlo, IDataRecord
pero sin ningún beneficio. DataTable
fue diseñado para facilitar la carga de una vez, por lo que también puede usarlo, pero pierde el beneficio de cargar a pedido (con el lector de datos puede detener la carga en cualquier momento), como var dt = new DataTable(); dt.Load(reader); return dt.AsEnumerable().ToList();
. Hay muchas bibliotecas que pueden automatizar esto para usted, encuéntrelas aquí stackoverflow.com/questions/11988441 y aquí stackoverflow.com/questions/1464883
reader.Cast<IEnumerable<dynamic>>
y .Cast<dynamic>
, pero dice, Cannot convert method group 'Cast' to non-delegate type 'dynamic'. Did you intend to invoke the method?
¿qué hice mal allí? (Miré sus fuentes, pero le exigieron que supiera el nombre de la columna, lo cual no sé)
Si solo desea los nombres de columna, 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 necesita una fila, me gusta mi adición AdoHelper. Esta adición es excelente si tiene una consulta de una sola línea y no desea tratar con la tabla de datos en su código. Está devolviendo un diccionario de mayúsculas y minúsculas de nombres y valores de columna.
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;
}
throw ex;
Es una peor práctica.
Utilizo el método GetSchemaTable , que se expone a través de la interfaz IDataReader.
Use un método de extensió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;
}
Seguro que puedes.
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(" ");
}
}
Esto es originalmente de: http://www.dotnetjunkies.ddj.com/Article/B82A22D1-8437-4C7A-B6AA-C6C9BE9DB8A6.dcik