क्या आप 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
यह समझ में नहीं आता है कि कोई गणना योग्य इंटरफ़ेस नहीं है जो आपको कॉलम के माध्यम से पुनरावृत्त करने देता है।
जॉनफैक्स

61
थोड़ा छोटा:columns = Enumerable.Range(0, reader.FieldCount) .Select(reader.GetName).ToList();
एलेक्स

2
यह बहुत अच्छा काम करता है। मुझे यह भी पता चला कि मेरे कॉलम के नाम सभी बड़े थे जब तक कि मैं कॉलम नाम के आसपास के उद्धरणों का उपयोग नहीं करता। SELECT id AS "MyId" FROM table;
स्टाइल जूल

इसके सभी स्तंभों को लोअरकेस में लौटाएं। तालिका में कॉलम के नाम सभी बड़े हैं जैसे OBJECTID और रीडर ऑब्जेक्ट की तरह लोअरकेस पर लौट रहे हैं
मुनीम हबीब

2
। इसके मंद कॉलम () स्ट्रिंग = Enumerable.Range (0, cTab.FieldCount) .Select के रूप में (फंक्शन (एन) cTab.GetName (एन)) toArray
दुर्भाग्य

77

GetNameपर एक समारोह हैSqlDataReader जिस कॉलम इंडेक्स स्वीकार करता है और कॉलम का नाम देता है।

इसके विपरीत, GetOrdinalएक कॉलम नाम होता है और कॉलम इंडेक्स लौटाता है।


3
दो कारण: पहला, मूल पोस्टर ने अभी तक एक उत्तर नहीं चुना है, और दूसरी बात, ऐसे अन्य उत्तर हैं जो समस्या के 'समाधान' का अधिक विस्तृत विवरण देते हैं और फिर कार्यक्षमता का अस्तित्व है। निजी तौर पर, मुझे स्टीवन लियोन का जवाब सबसे अच्छा लगता है क्योंकि यह न केवल गेटनेम के बारे में बात करता है, बल्कि फील्डटाइप और डेटाटाइप में भी जाता है।
स्टीफन राइटन

1
GetOrdinalउत्तम था। मैं देख रहा था GetName, लेकिन मेरे मुद्दे के लिए बहुत क्लीनर समाधान GetOrdinal
गोयडे

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पहले दृष्टिकोण में कैश करते हैं, तो क्वेरी बहुत धीमी होने वाली है।


क्या वैल्यूज़ के साथ ऐसा करने का कोई तरीका है?
ट्रैविस हेटेर

@TravisHeeter मैं तुम्हें नहीं मिलता। किसके मान से कॉलम नाम खोजें?
नवफाल

मेरा मतलब है कि एक सूची में सेट परिणाम में मान प्राप्त करने के लिए सिर्फ एक पूर्व तरीका है, या शायद एक IEnumerable <गतिशील> वस्तु के लिए पूरी बात।
ट्रेविस हेटेर

@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?मैंने वहां क्या गलत किया? (मैं अपने स्रोतों को देखा है, लेकिन वे स्तंभ नाम पता करने के लिए आप की आवश्यकता है, जो मैं नहीं)
ट्रैविस 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
इसका सिर्फ एक उदाहरण है
याकिर मैन

5
Asawyer, आपको कम से कम क्यों कहना चाहिए। मुझे लगता है कि आप कहते हैं कि आपको "फेंक" का उपयोग करना चाहिए। इसके बजाय ताकि आप मूल स्टैक ट्रेस विवरण न खोएं।
ब्रेंट रिटेनहाउस


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();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.