2009-11-06 20 views
5

Estoy tratando de cargar un archivo csv en una tabla de datos usando oledb.Carga csv en oleDB y fuerza todos los tipos de datos inferidos a la cadena

Esto no es problema, pero lamentablemente uno de los campos que parece numérico tiene un valor de cadena en aproximadamente el 3% de los campos y por lo tanto no se rellena.

porque estoy convirtiendo el csv en xml realmente no me importa inferir los tipos de datos y simplemente necesito los datos en una cadena, ya que puedo lanzarlo más tarde en una fase Linq2XMl.

Espero poder hacer esto en la cadena de conexión.

No quiero simplemente copiar la tabla, configurarla con nuevas columnas con el tipo de datos que quiero y luego escribir los datos en ella porque eso implicaría cargar el archivo csv dos veces.

¿Alguna idea?

mi cadena de conexión actual es

Provider = Microsoft.Jet.OleDb.4.0; 'texto; HDR = Sí; FMT = Delimitado' Extended Properties =; Data Source =" + thefile.DirectoryName + ""; ..

Respuesta

6

Investigó un poco y la respuesta es usar schema.ini pero generarlo sobre la marcha para su conjunto de datos.

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

contiene la información requerida. para construir el esquema:

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

para cargar la tabla de datos CSV como

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

para convertir a 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

Perdón por arrastrar una pregunta anterior pero seguramente esto carga el csv ** antes ** hay un archivo schema.ini presente y como tal cuando llama a LoadCSV está cargando su tabla de datos con los datos incorrectos otra vez? En última instancia, va a tener que volver a llamar a loadcsv para usar realmente el schema.ini generado no? – DannyT

+0

cargo el csv para crear el archivo de esquema y lo vuelvo a cargar para obtener los datos. Lea el enlace al artículo de microsoft sobre cómo funcionan los archivos de esquema.El código aquí es solo fragmentos de las partes clave realmente. –

+0

esto está funcionando para mí. Gracias. –

0

para leer un CSV en un DataTable Recomiendo este CSV parser

es muy fácil de usar he aquí cómo usted puede utilizar para llenar un DataTable con datos de un delimitado por comas, cita calificado CSV:

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

Hay varias opciones que puede establecer: el delimitador, el carácter de cualificación de texto, si la primera línea en el CSV muestra encabezados de columna (si es verdadero, cada DataColumn en su DataTable se nombrará en consecuencia), etc.

Hay un número de analizadores de CSV rápidos y flexibles, pero por simples requisitos, este no puede ser mejor.

+0

gracias, mala voluntad comprobar que la biblioteca fuera. Realmente quiero resolver esto sin usar dlls externos si es posible. Pero gracias. –

+1

No necesita archivos DLL externos para esto. El artículo incluye la clase que puedes incluir en tu proyecto. –

Cuestiones relacionadas