2010-08-16 15 views
31

Ho un file CSV che voglio leggere in una lista. Ecco un esempio di file:CSV per mappatura modello oggetto

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 

so di poter leggere manualmente nel file CSV e creare l'elenco utilizzando uno StreamReader normale, ma mi chiedevo se ci fosse un modo migliore, magari utilizzando LINQ?

+0

Per un elenco di cosa? Hai già una lezione? Il tipo anonimo è ok? – svick

+0

Ho una classe che rappresenta i dati nel csv. – mpenrow

risposta

35

È possibile utilizzare un codice semplice come questo, che ignora l'intestazione e non funziona con le virgolette, ma potrebbe essere sufficiente per le proprie esigenze.

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]) 
} 

Oppure è possibile utilizzare una libreria, come altri suggerito.

+3

Questo non funzionerà con dati stringa con virgole in essi. – terphi

+1

@terphi Ciò richiederebbe l'uso di virgolette e, come ho detto, il mio codice non funzionerà con quello. – svick

+0

Scusa, suppongo che stavo scremando. – terphi

31

Per i dati specifici indicati nella tua domanda ...

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

Se si hai già un tipo dichiarato per i tuoi dati, quindi puoi usare quello piuttosto che il tipo anonimo.

Si noti che questo codice non è robusto per tutto. Non gestirà correttamente i valori contenenti virgole/newline, ecc., Valori di stringa citati o qualcuna delle altre cose esoteriche che si trovano spesso nei file CSV.

+0

Sto cercando di capire in che modo le colonne: Plant, Material .... possono essere definite in fase di runtime, qualsiasi soluzione? –

6

Ho scritto una semplice libreria per consentire agli sviluppatori di utilizzare LINQ su file CSV. Qui è il mio blog post su di esso: http://procbits.com/2010/10/11/using-linq-with-csv-files/

Nel tuo caso, si dovrebbe cambiare la stringa di intestazione per assomigliare a questo:

Plant,Material,DensityLbft3,StorageLocation 

E allora si potrebbe analizzare il file in questo modo:

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

È quindi possibile utilizzare LINQ in questo modo:

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

Speranza che aiuta o lavora per tu.

Problemi correlati