2010-08-16 9 views
31

Ich habe eine CSV-Datei, die ich in eine Liste einlesen möchte. Hier ist ein Beispiel-Datei:CSV zu Objektmodellzuordnung

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 

Ich weiß, ich manuell in der CSV-Datei lesen können und bauen die Liste ein normales Stream, aber ich frage mich, ob es einen besseren Weg, vielleicht mit LINQ?

+0

Zu einer Liste von was? Hast du schon eine Klasse dafür? Ist der anonyme Typ in Ordnung? – svick

+0

Ich habe eine Klasse, die die Daten in der CSV darstellt. – mpenrow

Antwort

35

Sie können einen einfachen Code wie diesen verwenden, der den Header ignoriert und nicht mit Anführungszeichen arbeitet, aber möglicherweise für Ihre Bedürfnisse ausreicht.

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

Oder Sie können eine Bibliothek verwenden, wie andere vorgeschlagen.

+3

Dies funktioniert nicht für String-Daten mit Kommas in ihnen. – terphi

+1

@terphi Das würde erfordern Zitate verwenden und wie ich schon sagte, mein Code wird nicht damit arbeiten. – svick

+0

Entschuldigung, ich habe abgeschöpft. – terphi

31

Für die spezifischen Daten in Ihrer Frage gezeigt ...

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

Wenn Sie Haben Sie bereits einen Typ für Ihre Daten deklariert, dann können Sie diesen anstelle des anonymen Typs verwenden.

Beachten Sie, dass dieser Code nicht robust ist überhaupt. Es wird nicht korrekt mit Werten umgehen, die Kommas/Zeilenumbrüche usw., String-Werte in Anführungszeichen oder andere esoterische Elemente enthalten, die häufig in CSV-Dateien vorkommen.

+0

Ich versuche einen Weg zu finden, wo die Spalten: Werk, Material .... zur Laufzeit beliebig definiert werden können? –

6

Ich schrieb eine einfache Bibliothek, damit Entwickler LINQ auf CSV-Dateien verwenden können. Hier ist meine Blog-Post über sie: http://procbits.com/2010/10/11/using-linq-with-csv-files/

In Ihrem Fall müßten Sie Ihre Kopfzeichenfolge ändern wie folgt aussehen:

Plant,Material,DensityLbft3,StorageLocation 

Und dann könnten Sie die Datei wie folgt analysieren:

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

Sie könnten dann LINQ wie folgt aus:

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

Hoffnung, die oder arbeitet trägt dazu bei, Sie.