2010-08-16 2 views
31

У меня есть файл CSV, который я хочу прочитать в списке. Вот пример файла:CSV для сопоставления объектной модели

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 

Я знаю, что могу вручную прочитать в файле CSV и создать список, используя обычный StreamReader, но мне было интересно, если есть лучший способ, возможно, с помощью LINQ?

+0

К списку того, что? У вас уже есть класс для этого? Является анонимным типом? – svick

+0

У меня есть класс, который представляет данные в csv. – mpenrow

ответ

35

Вы можете использовать простой код, подобный этому, который игнорирует заголовок и не работает с кавычками, но может быть достаточным для ваших нужд.

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

Или вы можете использовать библиотеку, как и другие.

+3

Это не будет работать для строковых данных с запятыми. – terphi

+1

@terphi Для этого потребуется использовать кавычки, и, как я уже сказал, мой код не будет работать с этим. – svick

+0

Извините, догадываюсь, что я снимался. – terphi

31

Для конкретных данных, представленных на ваш вопрос ...

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

Если вы уже имеют тип, объявленный для ваших данных, тогда вы можете использовать это, а не анонимный тип.

Обратите внимание, что этот код не является надежным вообще. Он не будет корректно обрабатывать значения, содержащие запятые/новые строки и т. Д., Цитируемые строковые значения или любые другие эзотерические материалы, которые часто встречаются в файлах CSV.

+0

Я пытаюсь выяснить способ, по которому столбцы: Plant, Material .... могут быть определены во время выполнения, любое решение? –

6

Я написал простую библиотеку, чтобы разработчики могли использовать LINQ для CSV-файлов. Вот мой блог об этом: http://procbits.com/2010/10/11/using-linq-with-csv-files/

В вашем случае, вы должны изменить строку заголовка, чтобы выглядеть следующим образом:

Plant,Material,DensityLbft3,StorageLocation 

И тогда вы могли бы разобрать этот файл, как это:

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

Вы могли бы использовать LINQ, как это:

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

Надежда, что помогает или работает вы.

Смежные вопросы