2009-07-30 9 views
37

में कोई कॉलम मौजूद है या नहीं, यह देखने का कोई तरीका है कि IDataReader- आधारित ऑब्जेक्ट में कोई फ़ील्ड मौजूद है या नहीं, केवल एक indexOutOfRangeException की जांच कर रहा है?यह देखने के लिए जांच कर रहा है कि डेटा रीडर

संक्षेप में, मेरे पास एक तरीका है जो आईडीटाइडर-आधारित ऑब्जेक्ट लेता है और रिकॉर्ड की दृढ़ता से टाइप की गई सूची बनाता है। 1 उदाहरण में, एक डेटा रीडर में एक ऐसा क्षेत्र होता है जो अन्य नहीं करते हैं। मैं वास्तव में उन सभी प्रश्नों को फिर से लिखना नहीं चाहता हूं जो इस विधि को इस क्षेत्र के कुछ रूपों को शामिल करने के लिए फ़ीड करते हैं, यदि मुझे ऐसा नहीं करना है। एकमात्र तरीका यह है कि मैं यह पता लगाने में सक्षम हूं कि अब तक यह कैसे करना है, 1 अद्वितीय फ़ील्ड को नीचे दिखाए गए प्रयास/पकड़ ब्लॉक में फेंकना है।

try 
{ 
    tmp.OptionalField = reader["optionalfield"].ToString(); 
} 
catch (IndexOutOfRangeException ex) 
{ 
    //do nothing 
} 

वहाँ एक क्लीनर तरीका अन्य प्रश्नों के लिए "वैकल्पिक फ़ील्ड" जोड़ने या लोड हो रहा है विधि को कॉपी तो 1 संस्करण वैकल्पिक फ़ील्ड का उपयोग करता है और अन्य नहीं है की कमी है?

मैं 2.0 फ्रेमवर्क में भी हूं।

+1

मैं सोच रहा हूँ क्यों एमएस कोई DataReader – FLICKER

उत्तर

52

मैंने reader.GetName(int) विधि का उपयोग करके समाधान ढूंढना समाप्त कर दिया। मैंने तर्क को शामिल करने के लिए नीचे दी गई विधि बनाई है।

public bool ColumnExists(IDataReader reader, string columnName) 
{ 
    for (int i = 0; i < reader.FieldCount; i++) 
    { 
     if (reader.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase)) 
     { 
      return true; 
     } 
    } 

    return false; 
} 
+8

आप if-statement में सुधार कर सकते हैं: अगर (reader.GetName (i) .quals (कॉलमनाम, स्ट्रिंग कॉम्परिसन। इन्विरिएंट कल्चर इग्नोरकेस)) – Brabbeldas

+0

क्या होगा यदि उपनाम का उपयोग किया जाता है? उस मामले में तुलना निश्चित रूप से गलत होगी? – Murphybro2

6

प्रकट होता है कि मैं सही हूं। मैं जानता हूं कि आपके वास्तविक कॉलम नाम वहां हैं, लेकिन मैं गलत पथ पर जा रहा था। This reference ने चीजों को थोड़ा सा साफ़ करने में मदद की, लेकिन मुझे अभी भी यकीन नहीं है कि ऐसा करने का एक शानदार तरीका है या नहीं। ऊपर के लिंक से अनुकूलित, आपको निम्न के साथ अपने कॉलम के सभी की एक सूची प्राप्त कर सकते हैं:

List<string> myCols = new List<string>(); 
DataTable schema = reader.GetSchemaTable(); 
foreach (DataRow row in schema.Rows) 
{ 
    myCols.Add(row[schema.Columns["ColumnName"]]); 
} 

दुर्भाग्य से ऐसा लगता है कि आप कर सकते हैं सूचकांक द्वारा केवल पहुँच schema.Rows, इसलिए मैं नहीं यकीन है कि आप के आसपास मिल सकता है कर रहा हूँ नाम से जांचने से पहले पंक्तियों के माध्यम से लूपिंग। उस स्थिति में, आपका मूल समाधान कहीं अधिक सुरुचिपूर्ण लगता है!

नोट: मेरे मूल उत्तर ने केवल कॉलम की उपस्थिति की जांच करने का सुझाव दिया: reader.GetSchemaTable()। कॉलम ["optionalfield"]।

+0

को यह समारोह जोड़ा गया है GetSchemaTable() में गहरी देखने के बाद, इसे पाने के लिए प्रकट होता है: यदि एक स्तंभ मौजूद है

var cols = reader.GetSchemaTable() .Rows .OfType<DataRow>() .Select(row => row["ColumnName"]); 

या जाँच करने के लिए पूरी तरह से अलग कॉलम मेटाडेटा और अंतर्निहित तालिका नहीं। IsColumnSet और ColumnSize जैसे स्तंभ प्रस्तुत किए गए हैं और वास्तविक फ़ील्ड नहीं हैं। – JamesEggers

+0

मुझे प्राप्त होने वाले कॉलम की एक सूची इस पृष्ठ की सूची में मिल सकती है: http://msdn.microsoft.com/en-us/library/system.data।sqlclient.sqldatareader.getschematable% 28VS.80% 29.aspx – JamesEggers

3

एक DataTable में लोड यह और फिर आप स्तंभ के लिए जाँच कर सकते हैं:

DataTable dataTable = new DataTable(); 
dataTable.Load(reader); 
foreach (var item in dataTable.Rows) 
{ 
    bool columnExists = item.Table.Columns.Contains("ColumnName"); 
} 
1

इतना जटिलता की आवश्यकता नहीं है, बस इस:

bool bFieldExists = datareader.GetSchemaTable().Columns.Contains(strFieldName); 
+4

दुर्भाग्यवश उस संदर्भ में "कॉलम" IDataReader के बारे में मेटाडेटा के कॉलम हैं, आईडीटाइडर की कॉलम की सूची नहीं। GetSchemaTable() DataTable के भीतर प्रत्येक पंक्ति datareader में एक कॉलम है। – JMD

+0

यदि आप .NET 2.0 तक सीमित नहीं हैं, तो आप बस यह कर सकते हैं: bool bfieldExists = datareader.GetSchemaTable()। कॉलम। चयन करें (o => o.Name)। (MyColumnName) का चयन करें; – pqsk

5

यह काम करना चाहिए, कोशिश यह:

private static bool ColumnExists(SqlDataReader reader, string columnName) 
     { 
      using (var schemaTable = reader.GetSchemaTable()) 
      { 
       if (schemaTable != null) 
        schemaTable.DefaultView.RowFilter = String.Format("ColumnName= '{0}'", columnName); 

       return schemaTable != null && (schemaTable.DefaultView.Count > 0); 
      } 
     } 
18

निम्नलिखित दे देंगे आप डेटा रीडर दिए गए कॉलम नाम स्ट्रिंग की एक सूची। (याद रखें कि परिणाम अंतिम पढ़ने पर आधारित हैं, इसलिए पाठक जो पढ़ता है उसके आधार पर यह वही नहीं हो सकता है)।

public bool ColumnExists(IDataReader reader, string columnName) 
{ 

    return reader.GetSchemaTable() 
       .Rows 
       .OfType<DataRow>() 
       .Any(row => row["ColumnName"].ToString() == columnName); 
} 
+0

यह LINQ का उपयोग करता है जिसके लिए .NET 3.5 या बाद की आवश्यकता होती है। .NET 2.0 पर काम नहीं करता है जिसे ओपी ने कहा था कि वह उपयोग कर रहा था। – Scott

+1

ColumnExists 'एक अच्छा काम है। कृपया ध्यान दें, जैसा कि उदाहरण कोड के ऊपर लिखा गया है टूटा हुआ है। आपको तुलना में एक स्पष्ट कलाकार जोड़ना होगा, अन्यथा यह संदर्भ तुलना का उपयोग करता है और हमेशा झूठा रिटर्न देता है। कोई भी (पंक्ति => (स्ट्रिंग) पंक्ति ["कॉलमनाम"] == कॉलमनाम); –

6
Enumerable.Range(0, reader.FieldCount).Any(i => reader.GetName(i) == "ColumnName") 
+1

यह लिंक का उपयोग करता है जिसके लिए .NET 3.5 या बाद की आवश्यकता होती है। .NET 2.0 पर काम नहीं करता है जिसे ओपी ने कहा था कि वह उपयोग कर रहा था। – Scott

संबंधित मुद्दे