2010-08-16 4 views
31

Tengo un archivo CSV que deseo leer en una lista. Aquí está un ejemplo de archivo:Asignación de modelo de CSV a objeto

Plant,Material,"Density, Lb/ft3",Storage Location 
FRED,10000477,64.3008,3300 
FRED,10000479,62.612,3275 
FRED,10000517,90,3550 
FRED,10000517,72,3550 
FRED,10000532,90,3550 
FRED,10000532,72,3550 
FRED,10000550,97,3050 

Sé que puedo leer manualmente en el archivo CSV y construir la lista mediante un StreamReader normal, pero me preguntaba si había una manera mejor, tal vez usando LINQ?

+0

¿A una lista de qué? ¿Ya tienes una clase para eso? ¿El tipo anónimo está bien? – svick

+0

Tengo una clase que representa los datos en el csv. – mpenrow

Respuesta

35

Puede usar un código simple como este, que ignora el encabezado y no funciona con comillas, pero puede ser suficiente para sus necesidades.

from line in File.ReadAllLines(fileName).Skip(1) 
let columns = line.Split(',') 
select new 
{ 
    Plant = columns[0], 
    Material = int.Parse(columns[1]), 
    Density = float.Parse(columns[2]), 
    StorageLocation = int.Parse(columns[3]) 
} 

O puede utilizar una biblioteca, como otras sugeridas.

+3

Esto no funcionará para datos de cadena con comas en ellos. – terphi

+1

@terphi Eso requeriría usar comillas y como dije, mi código no funcionará con eso. – svick

+0

Lo siento, supongo que estaba desnatando. – terphi

31

Para los datos específicos que se muestran en su pregunta ...

var yourData = File.ReadAllLines("yourFile.csv") 
        .Skip(1) 
        .Select(x => x.Split(',')) 
        .Select(x => new 
           { 
            Plant = x[0], 
            Material = x[1], 
            Density = double.Parse(x[2]), 
            StorageLocation = int.Parse(x[3]) 
           }); 

Si ya tiene un tipo declarado para sus datos, entonces puede usarlo en lugar del tipo anónimo.

Tenga en cuenta que este código no es robusto en absoluto. No manejará correctamente los valores que contienen comas/líneas nuevas, etc., valores de cadena entrecomillados, o cualquiera de las otras cosas esotéricas que a menudo se encuentran en los archivos CSV.

+0

Estoy tratando de encontrar una forma en la que las columnas: Planta, Material ... se puedan definir en tiempo de ejecución, ¿alguna solución? –

6

Escribí una biblioteca simple para permitir a los desarrolladores usar LINQ en archivos CSV. Aquí está mi blog sobre él: http://procbits.com/2010/10/11/using-linq-with-csv-files/

En su caso, usted tiene que cambiar su cadena de encabezado a tener este aspecto:

Plant,Material,DensityLbft3,StorageLocation 

Y entonces se podría analizar el archivo de la siguiente manera:

var linqCSV = new CsvToXml("csvfile", true); 
linqCsv.TextQualifier = null; 

linqCsv.ColumnTypes.Add("Plant", typeof(string)); 
linqCsv.ColumnTypes.Add("Material", typeof(int)); 
linqCsv.ColumnTypes.Add("DensityLbft3", typeof(double)); 
linqCsv.ColumnTypes.Add("StorageLocation", typeof(int)); 

linqCsv.Convert(); 

a continuación, puede utilizar LINQ como esto:

var items = from item in linqCsv.DynamicRecords 
      where item.Plant == "Fred" && item.DensityLbft3 >= 62.6 
      orderby item.StorageLocation 
      select item; 

Espero que ayude o trabaja para tú.

Cuestiones relacionadas