2009-11-06 9 views
5

Sto tentando di caricare un file csv in un datatable utilizzando oledb.Caricare csv in oleDB e forzare tutti i tipi di dati dedotti alla stringa

Questo non è un problema ma sfortunatamente uno dei campi che sembra numerico ha un valore di stringa in circa il 3% dei campi e quindi non viene popolato.

perché nella conversione di csv in xml non mi interessa davvero dedurre i tipi di dati e semplicemente ho bisogno dei dati in una stringa, dato che posso lanciarlo successivamente in una fase Linq2XMl.

Spero di essere in grado di farlo nella stringa di connessione.

Non voglio copiare semplicemente la tabella, configurarla con nuove colonne con il tipo di dati desiderato e quindi scrivere i dati in essa perché ciò implicherebbe il caricamento del file csv due volte.

qualche idea?

mia stringa di connessione corrente è

Provider = Microsoft.Jet.OLEDB.4.0; Dati Source =" + thefile.DirectoryName + "; estesa Properties = 'text; HDR = Yes; FMT = delimitato'"; ..

risposta

6

Qualche researchand la risposta è utilizzare uno schema.ini ma generarlo al volo per il set di dati.

http://msdn.microsoft.com/en-us/library/ms709353(VS.85).aspx

contiene le informazioni richieste. per costruire lo schema:

public static void ConstructSchema(FileInfo theFile) 
    { 
     StringBuilder schema = new StringBuilder(); 
     DataTable data = LoadCSV(theFile); 
     schema.AppendLine("[" + theFile.Name + "]"); 
     schema.AppendLine("ColNameHeader=True"); 
     for (int i = 0; i < data.Columns.Count; i++) 
     { 
      schema.AppendLine("col" + (i + 1).ToString() + "=" + data.Columns[i].ColumnName + " Text"); 
     } 
     string schemaFileName = theFile.DirectoryName + @"\Schema.ini"; 
     TextWriter tw = new StreamWriter(schemaFileName); 
     tw.WriteLine(schema.ToString()); 
     tw.Close(); 
    } 

per caricare il CSV come DataTable

public static DataTable LoadCSV(FileInfo theFile) 
    { 
     string sqlString = "Select * FROM [" + theFile.Name + "];"; 
     string conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" 
      + theFile.DirectoryName + ";" + "Extended Properties='text;HDR=YES;'"; 
     DataTable theCSV = new DataTable(); 

     using (OleDbConnection conn = new OleDbConnection(conStr)) 
     { 
      using (OleDbCommand comm = new OleDbCommand(sqlString, conn)) 
      { 
       using (OleDbDataAdapter adapter = new OleDbDataAdapter(comm)) 
       { 
        adapter.Fill(theCSV); 
       } 
      } 
     } 
     return theCSV; 
    } 

convertire in xml

public static XElement GetXMLFromCSV(FileInfo theFile, string rootNodeName, string itemName) 
    { 
     XElement retVal; 
     DataTable data; 
     data = CrateCsvAndSchema(theFile); 
     DataSet ds = new DataSet(rootNodeName); 
     data.TableName = itemName; 
     ds.Tables.Add(data); 
     retVal = XElement.Parse(ds.GetXml()); 
     return retVal; 
    } 
+1

Ci scusiamo per il trascinamento di una vecchia domanda, ma sicuramente questo carica il csv ** prima ** esiste un file schema.ini e come tale quando chiami LoadCSV stai caricando di nuovo il tuo datatable con i dati errati? Alla fine finirai per dover chiamare di nuovo loadcsv per utilizzare effettivamente lo schema.ini generato? – DannyT

+0

carico il file CSV per creare il file dello schema, quindi lo carica di nuovo per ottenere i dati.leggi il collegamento all'articolo di microsoft su come funzionano i file dello schema.Il codice qui è solo frammenti delle parti chiave davvero. –

+0

questo sta funzionando per me. Grazie. –

0

per leggere un file CSV in un DataTable consiglio questo CSV parser

E 'davvero facile da usare Ecco come è possibile utilizzarlo per riempire un DataTable con i dati provenienti da una virgola delimitato, citazione qualificato CSV:

DataTable dt = null; 
    using (GenericParserAdapter gp = new GenericParser.GenericParserAdapter(yourCsvFullname)) { 
     dt = gp.GetDataTable(); 
    } 

Ci sono un certo numero di opzioni che puoi impostare: il delimitatore, i caratteri di qualifica del testo se la prima riga nel CSV mostra le intestazioni di colonna (se vero, ogni DataColumn nel tuo DataTable sarà nominata di conseguenza), ecc.

Ci sono un certo numero di parser CSV veloci e flessibili là fuori, ma per esigenze semplici questo non può essere battuto.

+0

grazie, malato verificherà quella libreria out. Voglio davvero risolvere questo problema senza utilizzare DLL esterne se possibile. Ma grazie. –

+1

Non hai bisogno di DLL esterne per questo. L'articolo include la classe che puoi includere nel tuo progetto. –

Problemi correlati