คุณจะได้รับชื่อคอลัมน์จาก SqlDataReader หรือไม่?


276

หลังจากเชื่อมต่อกับฐานข้อมูลที่ผมได้รับชื่อของคอลัมน์ทั้งหมดที่ถูกส่งกลับมาในของฉันSqlDataReader?

คำตอบ:


460
var reader = cmd.ExecuteReader();

var columns = new List<string>();

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

หรือ

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

71
มันเป็นเรื่องบ้าที่ไม่มีอินเทอร์เฟซนับไม่ได้ที่ให้คุณวนซ้ำผ่านคอลัมน์
JohnFx

61
สั้นกว่าเล็กน้อย:columns = Enumerable.Range(0, reader.FieldCount) .Select(reader.GetName).ToList();
อเล็กซ์

2
มันใช้งานได้ดี ฉันยังพบว่าชื่อคอลัมน์ของฉันเป็นตัวพิมพ์ใหญ่ทั้งหมดเว้นแต่ฉันจะใช้เครื่องหมายคำพูดรอบชื่อคอลัมน์ SELECT id AS "MyId" FROM table;
สไตล์

ครับมันกลับชื่อคอลัมน์ทั้งหมดในตัวพิมพ์เล็ก ชื่อคอลัมน์ในตารางเป็นตัวพิมพ์ใหญ่ทั้งหมดเช่น OBJECTID และผู้อ่านจะส่งคืนตัวพิมพ์เล็กเช่น objectid
Muneem Habib

2
คอลัมน์ Dim ของมัน () As String = Enumerable.Range (0, cTab.FieldCount) .Select (ฟังก์ชั่น (n) cTab.GetName (n)) ToArray
swe

77

มีGetNameฟังก์ชั่นSqlDataReaderที่ยอมรับดัชนีคอลัมน์และส่งคืนชื่อของคอลัมน์

ในทางกลับกันมีสิ่งGetOrdinalที่ใช้ในชื่อคอลัมน์และส่งกลับดัชนีคอลัมน์


3
สองเหตุผล: อันดับแรกผู้โพสต์ดั้งเดิมยังไม่ได้เลือกคำตอบและประการที่สองมีคำตอบอื่น ๆ ที่ให้คำอธิบายโดยละเอียดเพิ่มเติมเกี่ยวกับ 'การแก้ปัญหา' ของปัญหาแล้วเพียงแค่มีฟังก์ชันการทำงานอยู่ โดยส่วนตัวแล้วฉันชอบ Steven Lyons มากที่สุดเพราะไม่เพียง แต่พูดถึง GetName เท่านั้น แต่ยังรวมถึง FieldType และ DataType ด้วย
Stephen Wrighton

1
GetOrdinalสมบูรณ์แบบ ผมกำลังมองหาแต่วิธีการแก้ปัญหามากสะอาดสำหรับปัญหาของฉันด้วยGetName GetOrdinal
goodeye

43

คุณสามารถรับชื่อคอลัมน์จาก DataReader

นี่คือส่วนสำคัญ:

  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

พูดถึงแล้ว เพียงคำตอบของ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();

อันที่สองนั้นสะอาดกว่าและเร็วกว่ามาก แม้ว่าคุณจะแคชGetSchemaTableในแนวทางแรกการสืบค้นจะช้ามาก


มีวิธีทำเช่นนี้กับ Values ​​หรือไม่?
Travis Heeter

@ TravisHeeter ฉันไม่ได้รับคุณ ค้นหาชื่อคอลัมน์จากค่าของอะไร
nawfal

ฉันหมายถึงเพียงวิธีตะวันออกในการรับค่าในผลลัพธ์ที่กำหนดไว้ในรายการหรือบางทีอาจเป็นวัตถุ IE ที่นับไม่ถ้วน <dynamic> ทั้งหมด
Travis Heeter

ใช่ @TravisHeeter reader.Cast<IDataRecord>().ToList()สามารถทำ ฉันเชื่อว่าคุณสามารถใช้dynamicคำหลักที่นั่นแทนIDataRecordแต่ไม่มีประโยชน์ DataTableถูกออกแบบมาเพื่อความสะดวกในการโหลดเพียงครั้งเดียวเพื่อให้คุณสามารถใช้ที่มากเกินไป แต่คุณจะสูญเสียผลประโยชน์ของการโหลดตามความต้องการ (มีผู้อ่านข้อมูลที่คุณสามารถหยุดการโหลดที่จุดใด ๆ ) var dt = new DataTable(); dt.Load(reader); return dt.AsEnumerable().ToList();เช่น มีห้องสมุดจำนวนมากซึ่งสามารถอัตโนมัตินี้คุณจะพบพวกเขาที่นี่stackoverflow.com/questions/11988441และนี่stackoverflow.com/questions/1464883
Nawfal

ฉันพยายามreader.Cast<IEnumerable<dynamic>>และ.Cast<dynamic>แต่ก็บอกว่าCannot convert method group 'Cast' to non-delegate type 'dynamic'. Did you intend to invoke the method?ทำอะไรที่ไม่ถูกต้องมี? (ฉันดูที่แหล่งที่มาของคุณ แต่พวกเขาต้องการให้คุณรู้ชื่อคอลัมน์ซึ่งฉันไม่ได้ทำ)
Travis Heeter

6

หากคุณต้องการชื่อคอลัมน์เท่านั้นคุณสามารถทำได้:

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

แต่ถ้าคุณต้องการเพียงแถวเดียวฉันชอบการเพิ่ม AdoHelper ของฉัน การเพิ่มนี้เป็นสิ่งที่ดีถ้าคุณมีคิวรีบรรทัดเดียวและคุณไม่ต้องการจัดการกับตารางข้อมูลในโค้ดของคุณ มันกำลังส่งคืนพจนานุกรมที่ไม่สนใจตัวพิมพ์เล็กของชื่อคอลัมน์และค่า

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;เป็นการปฏิบัติที่เลวร้ายที่สุด
asawyer

2
มันเป็นเพียงตัวอย่าง
Yakir Manor

5
อย่างน้อยคุณก็ควรจะพูดว่าทำไม ฉันคิดว่าคุณกำลังจะพูดว่าคุณควรใช้ "throw;" แต่คุณจะไม่สูญเสียรายละเอียดการติดตาม strack ดั้งเดิม
Brent Rittenhouse


3

ใช้วิธีการขยาย:

    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

คุณสามารถทำได้


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

}

นี้มาจาก: http://www.dotnetjunkies.ddj.com/Article/B82A22D1-8437-4C7A-B6AA-C6C9BE9DB8A6.dcik


1

มันง่ายกว่าที่จะบรรลุใน 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();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.