Search code examples
c#csvoledb

Strange behavior of exception with oledb to csv


I have an application, which connects to csv-data via ole-db. The csv-data is loaded into a datatable. Then i iterate through the datarows of the table. For each datarow a function is called, which inserts the data into a mysql-db.

private void ConvertCSVDocument()
{
    try
    {
        using (var dataSet = base.Source.CreateDataSet())
        {
            using (var dataTable = dataSet.Tables[0])
            {
                base.Progress(dataTable.Rows.Count, 0);

                for (int i = 0; i < dataTable.Rows.Count; i++)
                {
                    try
                    {
                        this.ConvertCSVDocumentRow(dataTable.Rows[i]);
                    }
                    catch (Exception e)
                    {
                        base.Report($"Row {i.ToString("0000")} {e}");
                    }
                    finally
                    {
                        base.Progress(dataTable.Rows.Count, i);
                    }
                }
            }
        }
    }
    catch (Exception e)
    {
        base.Report($"Fatal error: {e}");
    }
}

When i Execute this code, an exception is thrown on the line where my dataSet is created (using var dataSet = base.Source.CreateDataSet())

I get the following message:

Fatal error: System.ArgumentException: illegal OleAut-Date. bei System.DateTime.DoubleDateToTicks(Double value) bei System.Data.OleDb.ColumnBinding.Value_DATE() bei System.Data.OleDb.ColumnBinding.Value() bei System.Data.OleDb.OleDbDataReader.GetValues(Object[] values) bei System.Data.ProviderBase.DataReaderContainer.CommonLanguageSubsetDataReader.GetValues(Object[] values) bei System.Data.ProviderBase.SchemaMapping.LoadDataRow() bei System.Data.Common.DataAdapter.FillLoadDataRow(SchemaMapping mapping) bei System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue) bei System.Data.Common.DataAdapter.Fill(DataTable[] dataTables, IDataReader dataReader, Int32 startRecord, Int32 maxRecords) bei System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) bei System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior) bei System.Data.Common.DbDataAdapter.Fill(DataTable dataTable) bei FooKonvert.Context.Csv.CsvContext.CreateDataSet() in D:\Projekte\csharp\Tools\Foo\FooKonvert\Context\Csv\CsvContext.cs:Zeile 42. bei FooKonvert.Converter.FooConverter.ConvertCSVDocument() in D:\Projekte\csharp\Tools\Foo\FooKonvert\Converter\FooConverter.cs:Zeile 395.

When i comment out the line this.ConvertCSVDocumentRow(dataTable.Rows[i]); The exception is not thrown and the iteration throug the datarows is successfull.

Can someone explain what is happening? The error occurs before the line is even called, when the exception is thrown, this function has not even been called.

#

Here is how i create the dataset:

public DataSet CreateDataSet()
{
    string connectionString = $"provider=Microsoft.Jet.OLEDB.4.0; data source={this.FilePath};Extended Properties=\"Text;HDR=yes;\"";

    using (OleDbConnection connection = new OleDbConnection(connectionString))
    {
        connection.Open();

        OleDbDataAdapter adapter = new OleDbDataAdapter($"SELECT * FROM [{this.FileName}]", connection);

        var dataSet = new DataSet();
        var dataTable = new DataTable();

        adapter.Fill(dataTable);
        dataSet.Tables.Add(dataTable);

        return dataSet;
    }
}

Here is an abstract version of the ConvertSCVDocumentRow-Function:

try
{
    var forename = dataRow["some_column_name_1"].ToString();
    var surename = dataRow["some_column_name_2"].ToString();

    int person_ident = GetIdentForPerson(forename,surename);

    if (person_ident <= 0)
    {
        InsertPerson(forename,surename);                
    }
}
catch(Exception e)
{
    throw new Exception("Failed to convert person!", e);
}

Solution

  • Like Rune Grimstadt mentioned there are other options for reading csv-files to a dataset. Here is a solution with FileStream i fount on the internet:

    public DataTable CreateDataTable()
    {
        DataTable dt = new DataTable();
        FileStream aFile = new FileStream(this.FilePath, FileMode.Open);
        using (StreamReader sr = new StreamReader(aFile, System.Text.Encoding.Default))
        {
            string strLine = sr.ReadLine();
            string[] strArray = strLine.Split(';');
    
            foreach (string value in strArray)
                dt.Columns.Add(value.Trim());
    
            DataRow dr = dt.NewRow();
    
            while (sr.Peek() > -1)
            {
                strLine = sr.ReadLine();
                strArray = strLine.Split(';');
                dt.Rows.Add(strArray);
            }
        }
        return dt;
    }
    

    This worked for me.