2009-11-06 9 views
5

Próbuję wczytać plik CSV do datatable za pomocą oledb.Załaduj plik csv do biblioteki oleDB i wymuś wszystkie typy danych na łańcuchy znaków

To nie jest problem, ale niestety jedno z pól, które wygląda na liczbowy ma wartość ciągu w około 3% pól, więc nie jest wypełniane.

ponieważ im konwertuję CSV na xml naprawdę nie dbam o wnioskowanie typów danych i po prostu potrzebuję danych w łańcuchu, ponieważ mogę go później przesłać w fazie Linq2XMl.

Mam nadzieję, że będę mógł to zrobić w ciągu połączenia.

Nie chcę po prostu skopiować tabelę, ustawić go w nowe kolumny z typem danych chcę, a następnie zapisać dane do niego, bo to wiązałoby ładowania pliku csv dwukrotnie.

jakieś pomysły?

mój obecny ciąg połączenia jest

Provider = Microsoft.Jet.OLEDB.4.0; Data Source =”+ thefile.DirectoryName + "; właściwości rozszerzone = 'text; HDR = Yes; FMT = separatorami'"; ..

Odpowiedz

6

Zrobiłem kilka badań i odpowiedź jest użyć schema.ini, ale wygenerować go w locie dla zbioru danych.

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

zawiera wymaganych informacji. skonstruować schemat:

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

załadować csv jako elementu 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; 
    } 

przekonwertować do formatu 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

Przepraszamy za przeciąganie starego pytania, ale z pewnością ładuje to plik csv ** przed ** istnieje plik schema.ini i jako takie, wywołując LoadCSV ponownie ładujesz swój datatable z niepoprawnymi danymi? W końcu będziesz musiał wywoływać ponownie loadcsv, aby faktycznie używać wygenerowanego schematu schema.ini? – DannyT

+0

Załaduj plik csv, aby utworzyć plik schematu, a następnie załaduj go ponownie, aby pobrać dane. Przejrzyj łącze do artykułu Microsoft o działaniu plików schematu.Tutaj kod jest po prostu fragmentami kluczowych części. –

+0

to działa dla mnie. Dzięki. –

0

do czytania CSV do DataTable polecam ten CSV parser

jest bardzo łatwy w użyciu Oto jak można użyć go do wypełniania DataTable z danych z oddzielonych przecinkami, cytuję zakwalifikowane csv:

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

Istnieje wiele opcji, które można ustawić: separator, tekstowe znaki kwalifikatorowe, niezależnie od tego, czy pierwszy wiersz w nagłówkach kolumn CSV pokazuje (jeśli prawdziwe, każda kolumna DataCable w DataTable będzie odpowiednio nazwana) itd.

Istnieje wiele szybkich, elastycznych analizatorów plików CSV, ale dla prostych wymagań nie można ich pokonać.

+0

thankyou, chory będzie sprawdzać tej biblioteki na zewnątrz. Naprawdę chcę rozwiązać ten problem bez korzystania z zewnętrznych bibliotek dll, jeśli w ogóle możliwe. Ale dzięki. –

+1

Nie potrzebujesz do tego zewnętrznych bibliotek DLL. Artykuł zawiera klasę, którą możesz dołączyć do swojego projektu. –