Antworten:
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();
columns = Enumerable.Range(0, reader.FieldCount) .Select(reader.GetName).ToList();
SELECT id AS "MyId" FROM table;
Es gibt eine GetName
Funktion, SqlDataReader
die den Spaltenindex akzeptiert und den Namen der Spalte zurückgibt.
Umgekehrt gibt es eine, GetOrdinal
die einen Spaltennamen aufnimmt und den Spaltenindex zurückgibt.
GetOrdinal
war perfekt. Ich suchte GetName
, aber viel sauberere Lösung für mein Problem mit GetOrdinal
.
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
}
Schon 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();
Der zweite ist sauberer und viel schneller. Selbst wenn Sie GetSchemaTable
beim ersten Ansatz zwischenspeichern, wird die Abfrage sehr langsam sein.
reader.Cast<IDataRecord>().ToList()
. Ich glaube, Sie könnten dort ein dynamic
Schlüsselwort verwenden, IDataRecord
aber ohne Nutzen. DataTable
wurde entwickelt, um das einmalige Laden zu vereinfachen, sodass Sie dies auch verwenden können, aber den Vorteil des Ladens bei Bedarf verlieren (mit dem Datenleser können Sie das Laden jederzeit beenden), wie z var dt = new DataTable(); dt.Load(reader); return dt.AsEnumerable().ToList();
. Es gibt viele Bibliotheken, die dies für Sie automatisieren können. Sie finden sie hier stackoverflow.com/questions/11988441 und hier stackoverflow.com/questions/1464883
reader.Cast<IEnumerable<dynamic>>
und .Cast<dynamic>
, aber es heißt, Cannot convert method group 'Cast' to non-delegate type 'dynamic'. Did you intend to invoke the method?
was habe ich dort falsch gemacht? (Ich habe mir Ihre Quellen angesehen, aber Sie mussten den Spaltennamen kennen, was ich nicht weiß.)
Wenn Sie nur die Spaltennamen möchten, können Sie Folgendes 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"));
}
}
Wenn Sie jedoch nur eine Zeile benötigen, gefällt mir mein AdoHelper-Zusatz. Dieser Zusatz ist ideal, wenn Sie eine einzeilige Abfrage haben und sich nicht mit der Datentabelle in Ihrem Code befassen möchten. Es wird ein Wörterbuch mit Spaltennamen und -werten zurückgegeben, bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird.
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;
ist eine schlechteste Praxis.
Ich verwende die GetSchemaTable- Methode, die über die IDataReader-Schnittstelle verfügbar gemacht wird.
Verwenden Sie eine Erweiterungsmethode:
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;
}
Sie können sicher.
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 von: http://www.dotnetjunkies.ddj.com/Article/B82A22D1-8437-4C7A-B6AA-C6C9BE9DB8A6.dcik