Reading a csv file into a DataTable with Linq

Some times ago i had the requirement to read a csv file into a DataTable and doint it the classical iterative way seems boring to me so i thought about the make all with one linq statement princip and tried to accomplish the whole processing with one linq statement. That are my results i want to share. I stated with the following statement.

public DataTable ImportFirstAdept(FileInfo fileInfo, char splitChar, Encoding encoding)
{
    var plainfileName = Path.GetFileName(fileInfo.FullName);
    DataTable dataTable = new DataTable(plainfileName);
    var allRows = ((Func)(() => File.ReadAllLines(fileInfo.FullName, encoding)))();
    allRows.
        Select(str => str.Split(splitChar)).
        First().
        Select(columnHeader => { return new DataColumn(columnHeader.Trim()); }).
        Foreach(column =>
        {
            dataTable.Columns.Add(column);
            return column;
        }).
        ToList();
    allRows.
        Select(str => str.Split(splitChar)).
        Skip(1).
        Select(strArray =>
        {
            var strings = new List();
            foreach (var s in strArray)
                strings.Add(s.Trim());
            return strings.ToArray();
        }).
        Select(st => dataTable.Rows.Add(st)).
        ToList();
    return dataTable;
}

The follwoing test shows how it works.

public void CsvToDataTableTest(string path)
{
    DirectoryInfo directoryInfo = new DirectoryInfo(path);            
    CsvImport cvsImport = new CsvImport();
    DataSet dataSet = new DataSet();
    if (directoryInfo.Exists)
    {
        foreach (var file in directoryInfo.EnumerateFiles("*.csv"))
        {
            DataTable dataTable = cvsImport.ImportFirstAdept(file, '\t', Encoding.Default);
            dataSet.Tables.Add(dataTable);
        }
    }
}

[TestMethod]
public void CsvToDataTablePrequelsTest()
{
    CsvToDataTableTest(@"CsvToDataTableWithLinq\bin\Debug");
}

If we look at the ImportFirstAdept method it does not use one linq statement it uses two linq statements. So that was not sufficiently and i wrote some extension methodes to only use one Linq statement for the processing of the csv file.

public static class CsvImportExtension
{
    public static void If(this IEnumerable source, Func ifFunc, 
        Action ifAction, Action elseAction)
    {
        var counter = 1;
        List ifActions = new List();
        List elseActions = new List();
        foreach (var item in source)
        {
            if (ifFunc(item, counter))                                    
            {
                ifActions.Add(item);
            }                           
            else
                elseActions.Add(item);
            counter++;                
        }
        ifAction(ifActions.AsEnumerable());
        elseAction(elseActions.AsEnumerable());
    }

    public static void If(this IEnumerable source, Func ifFunc,
        Action ifAction, Action elseAction)
    {
        List ifActions = new List();
        List elseActions = new List();
        foreach (var item in source)
        {
            if (ifFunc(item))
            {
                ifActions.Add(item);
            }
            else
                elseActions.Add(item);
        }
        ifAction(ifActions.AsEnumerable());
        elseAction(elseActions.AsEnumerable());
    }

    public static IEnumerable Foreach(this IEnumerable source, Func foreachFunc)
    {
        foreach (var item in source)
        {
            yield return foreachFunc(item);
        }
    }

    public static void Foreach(this IEnumerable source, Action foreachAction)
    {
        foreach (var item in source)
        {
            foreachAction(item);
        }
    }
}

That is the ImportSecondAdept method that uses the if and foreach extension methodes to only use one linq statement to process the csv file.

public DataTable ImportSecondAdept(FileInfo fileInfo, char splitChar, Encoding encoding)
{
    var plainfileName = Path.GetFileName(fileInfo.FullName);
    var dataTable = new DataTable(plainfileName);
    ((Func)(() => File.ReadAllLines(fileInfo.FullName, encoding)))().
        Foreach(str => str.Split(splitChar)).
        If((t, i) => i == 1,
        t =>
        {
            t.First().
            Foreach(columnHeader => { return new DataColumn(columnHeader.Trim()); }).
            Foreach(column =>
            {
                dataTable.Columns.Add(column);
            });                    
        },
        t =>
        {
            t.
            Foreach(strArray =>
            {
                var strings = new List();
                foreach (var s in strArray)
                    strings.Add(s.Trim());
                return strings.ToArray();
            }).
            Foreach(str => dataTable.Rows.Add(str)).
            ToList();                    
        }
        );           
    return dataTable;
}

That is the test to try it and the result of the second adept method.

public void CsvToDataTableTest(string path)
{
    DirectoryInfo directoryInfo = new DirectoryInfo(path);            
    CsvImport cvsImport = new CsvImport();
    DataSet dataSet = new DataSet();
    if (directoryInfo.Exists)
    {
        foreach (var file in directoryInfo.EnumerateFiles("*.csv"))
        {
            DataTable dataTable = cvsImport.ImportSecondAdept(file, '\t', Encoding.Default);
            dataSet.Tables.Add(dataTable);
        }
    }
}

[TestMethod]
public void CsvToDataTablePrequelsTest()
{
    CsvToDataTableTest(@"CsvToDataTableWithLinq\bin\Debug");
}

csvToDataSetWithLinq

So now it is only one linq statement and the one linq statement princip is suffused.