I'm attempting to find an elegant way to read a cvs string via 4.0 linq and have been somewhat unsuccessful due to embedded commas between quotes. Here is an example of 3 columns and 3 rows:
Date,Years,MemoText "2011-01-01","0.5","Memo Text
Memo Text continuing
And still continuing, and then comma, yet the memo is in quotes"
"2010-01-01","0.5","Memo Text, Memo without line breaks"
"2009-01-01","1.0","Plain memo text"
So far I've come up with the following faulty code as the pulling together other stack exchange bits. This doesn't work since carriage line feeds in memo text since carriage return line feeds break up memo text into multiple fields.
using (var reader = new StreamReader(getReader))
{
var records = reader.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
var enumRecords = records.Skip(1).Take(1);
using (var dc = new DataContext())
{
foreach (var record in enumRecords
.Select(x => x.Trim()
.Split(new char[] { ',' }))
.Select(fields => new Entity
{
Date = (!string.IsNullOrEmpty(record.ElementAt(0))) ? Convert.ToDateTime(record.ElementAt(0)) : default(DateTime),
DecimalYears = record.ElementAt(1),
MemoText = record.ElementAt(2)
}))
{
//Commit DataContext
}
}
}
No dice when splitting on commas alone since commas exist between quoted text:
using (var reader = new StreamReader(getReader))
{
var sdata = reader.ReadToEnd();
using (var dc = new DataContext())
{
var query = sdata
.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Replace(Environment.NewLine, string.Empty)
.Replace("\"\"", "\",\"")
.Select((i, n) => new { i, n })
.GroupBy(a => a.n / 3)
.Skip(1).Take(1);
foreach (var fields in query)
{
var newEntity = new Entity();
newEntity.Date = (!string.IsNullOrEmpty(fields.ElementAt(0).i)) ? Convert.ToDateTime(fields.ElementAt(0).i) : default(DateTime);
newEntity.DecimalYears = fields.ElementAt(1).i;
newEntity.MemoText = fields.ElementAt(2).i;
}
}
}
So far what seems like a simple objective is bordering on verbose ugly code, possibly someone out there has a clean and functional way to approach this using LINQ?