Search code examples
c#asp.net.netlinqtocsv

Convert IEnumerable string array to datatable


I have a csv file delimited with pipe(|). I am reading it using the following line of code:

IEnumerable<string[]> lineFields = File.ReadAllLines(FilePath).Select(line => line.Split('|'));

Now, I need to bind this to a GridView. So I am creating a dynamic DataTable as follows:

DataTable dt = new DataTable();
int i = 0;
foreach (string[] order in lineFields)
{
    if (i == 0)
    {                        
        foreach (string column in order)
        {
            DataColumn _Column = new DataColumn();
            _Column.ColumnName = column;
            dt.Columns.Add(_Column);
            i++;
            //Response.Write(column);
            //Response.Write("\t");
        }
    }
    else
    {
        int j = 0;
        DataRow row = dt.NewRow();
        foreach (string value in order)
        {
            row[j] = value;                            
            j++;

            //Response.Write(column);
            //Response.Write("\t");
        }
        dt.Rows.Add(row);
    }
    //Response.Write("\n");
}

This works fine. But I want to know if there is a better way to convert IEnumerable<string[]> to a DataTable. I need to read many CSVs like this, so I think the above code might have performance issues.


Solution

  • since, in your linked example, the file has a header row.

    const char Delimiter = '|';
    
    var dt = new DataTable;
    using (var m = File.ReadLines(filePath).GetEnumerator())
    {
        m.MoveNext();
        foreach (var name in m.Current.Split(Delimiter))
        {
            dt.Columns.Add(name);
        }
    
        while (m.MoveNext())
        {
            dt.Rows.Add(m.Current.Split(Delimiter));
        }
    }
    

    This reads the file in one pass.