2010-03-29 13 views
11

मेरे पास एक सिस्टम है। डेटा। डेटाटाबल जो एक CSV फ़ाइल पढ़कर पॉप्युलेट किया जाता है जो स्ट्रिंग के लिए प्रत्येक कॉलम के डेटाटाइप को सेट करता है।पॉप्युलेट किए गए डेटाटेबल कॉलम डेटा प्रकारों को बदलना

मैं डेटाटेबल की सामग्री को मौजूदा डेटाबेस तालिका में जोड़ना चाहता हूं - वर्तमान में यह स्रोत के रूप में डेटाटेबल के साथ एसक्यूएलकल्क कॉपी का उपयोग करके किया जाता है।

हालांकि, डेटाटेबल के कॉलम डेटा प्रकार को लक्ष्य डेटाबेस तालिका की स्कीमा से मेल खाने के लिए बदलने की आवश्यकता है, शून्य मानों को संभालना।

मैं एडीओ.NET से बहुत परिचित नहीं हूं इसलिए ऐसा करने का एक साफ तरीका खोज रहा है?

धन्यवाद।

उत्तर

10

आप डेटा के साथ पॉप्युलेट करने के बाद एक DataColumn की DataType नहीं बदल सकते। यह केवल पढ़ने योग्य संपत्ति नहीं है, लेकिन यदि आप पहले से डेटा के बाद इसे बदलने का प्रयास करते हैं तो आपको रनटाइम पर अपवाद प्राप्त होगा।

documentation से

: जब इस संपत्ति के बदलने के बाद स्तंभ डेटा भंडारण शुरू हो गया है

एक अपवाद उत्पन्न होता है।

तो तुम (यदि संभव हो) या तो सही कॉलम प्रकार सुनिश्चित करने के लिए शुरुआत में होगा, या आयात के लिए विशेष रूप से एक नया DataTable बना सकते हैं और मूल DataTable से डेटा कॉपी।

आप कस्टम IDataReader वर्ग है कि आपके DataTable से पढ़ता है और जस्ट-इन-समय रूपांतरण करता है और SqlBulkCopy है कि पारित लिख सकता है - यह एक बहुत अधिक कुशल होगा, लेकिन यह स्पष्ट रूप से त्वरित सुधार नहीं है।

+0

धन्यवाद - मुझे एहसास है कि मैं इसे एक बार पॉप्युलेट कर नहीं सकता हूं। जो मैं खोज रहा हूं वह सही डेटा प्रकारों के साथ दूसरा डेटाटेबल बनाने का तरीका है और फिर डेटा को पहले डेटाटेबल से आयात और परिवर्तित कर रहा है। दुर्भाग्यवश स्ट्रिंग के अलावा डेटा प्रकारों का उपयोग करने के लिए पहले डेटाटेबल के लिए यह संभव नहीं है। – TonE

+0

@TonE: ऐसा करने का एकमात्र तरीका मैं 'IDataReader' को लागू करना और' DataTable.Load' विधि का उपयोग करना होगा - लेकिन यदि आप ऐसा करने जा रहे हैं, तो आप केवल पाठक का उपयोग भी कर सकते हैं दूसरे 'डेटाटेबल' बनाने के बजाय 'SqlBulkCopy' के लिए। – Aaronaught

+0

यह एक दिलचस्प सुझाव है। क्या डेटाटेबल रीडर से प्राप्त करना संभव होगा, और यदि ऐसा है तो आप जानते हैं कि प्रकार बदलने की कार्यक्षमता प्रदान करने के लिए मुझे किन तरीकों को ओवरराइड करने की आवश्यकता होगी? बस समय की बाधाओं को देखते हुए यह अनुमान लगाने की कोशिश कर रहा है। – TonE

3

आपके द्वारा भरने वाले डेटाटेबल के डेटाटाइप सेट करना सुनिश्चित करें।

उदा .:

DataTable table = new DataTable("countries"); 
    table.Columns.Add("country_code", typeof (string)); 
    table.Columns.Add("country_name", typeof (string)); 
    //... 
    //Fill table 

या आप स्तंभ प्रकार बदल सकता है अगर वे संगत कर रहे हैं:

table.Columns["country_code"].DataType = typeof(string); 
+0

हाँ, यह वही है जो मैं वर्तमान में कर रहा हूं लेकिन वास्तव में दूसरे डेटाटेबल को सही ढंग से सेट प्रकारों के साथ पॉप्युलेट करना मुश्किल साबित कर रहा है। क्या ऐसा करने के लिए एक सरल तरीका है? – TonE

9

मैं काम करने के लिए इस सामान्य समारोह में लिखा था, यह मेरे लिए बहुत अच्छी तरह से काम करता है:

public static bool ChangeColumnDataType(DataTable table, string columnname, Type newtype) 
{ 
    if (table.Columns.Contains(columnname) == false) 
     return false; 

    DataColumn column= table.Columns[columnname]; 
    if (column.DataType == newtype) 
     return true; 

    try 
    { 
     DataColumn newcolumn = new DataColumn("temporary", newtype); 
     table.Columns.Add(newcolumn); 
     foreach (DataRow row in table.Rows) 
     { 
      try 
      { 
       row["temporary"] = Convert.ChangeType(row[columnname], newtype); 
      } 
      catch 
      { 
      } 
     } 
     table.Columns.Remove(columnname); 
     newcolumn.ColumnName = columnname; 
    } 
    catch (Exception) 
    { 
     return false; 
    } 

    return true; 
} 

तुम बस कोड को कॉपी और (यहाँ MyClass) एक वर्ग में रख सकते हैं, और इस तरह इसका इस्तेमाल एक उदाहरण के रूप:

MyClass.ChangeColumnDataType(table, "GEOST", typeof (int)); 
+1

एकमात्र समस्या - संग्रह के अंत में नया कॉलम जोड़ा जाता है, इसलिए, उदाहरण के लिए, आप इसे "autogeneratecolumns = true" के साथ ग्रिड पर बाध्य करते हैं, यह सामान्य स्थिति अलग होगी –

+1

ठीक किया गया :) :) और मेरे समाधान में इसका उपयोग किया गया यदि आपको कोई फर्क नहीं पड़ता: http://codecorner.galanter.net/2013/08/02/ado-net-datatable-change-column-datatype-after-table-is-populated-with-data/ –

1

आप csv फ़ाइल से पॉप्युलेट रहे हैं तो पहले datatable में स्कीमा पढ़ा तो स्तंभ के डेटाप्रकार बदल तो तालिका पॉप्युलेट। उदाहरण: मैं डेटा आयात करने के लिए एक्सएमएल फ़ाइल का उपयोग कर रहा हूं।

 DataSet dstemp = new DataSet(); 
     dstemp.ReadXmlSchema(@"D:\path of file\filename.xml"); 
     dstemp.Tables[0].Columns["Student_id"].DataType = typeof(Guid); 
     dstemp.ReadXml(@"D:\path of file\filename.xml"); 

मुझे लगता है कि यह आपके लिए काम करना चाहिए।

0

जैसे "एडी मोंज जूनियर" या "गिसवे" इसे प्राप्त नहीं कर सकते हैं।

लेकिन सही कॉलम ऑर्डर के साथ।

public static bool ChangeColumnDataType(DataTable table, string columnname, Type newtype){ 
    if (table.Columns.Contains(columnname) == false) 
     return false; 

    DataColumn column = table.Columns[columnname]; 
    if (column.DataType == newtype) 
     return true; 

    try{ 
     DataColumn newcolumn = new DataColumn("temporary", newtype); 
     table.Columns.Add(newcolumn); 

     foreach (DataRow row in table.Rows){ 
      try{ 
       row["temporary"] = Convert.ChangeType(row[columnname], newtype); 
      } 
      catch{} 
     } 
     newcolumn.SetOrdinal(column.Ordinal); 
     table.Columns.Remove(columnname); 
     newcolumn.ColumnName = columnname; 
    } 
    catch (Exception){ 
     return false; 
    } 

    return true; 
} 
संबंधित मुद्दे