1
votes

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);
}
1
Can you translate message after System.ArgumentException and provide ConvertCSVDocumentRow method? It's possible that you're using wrong method argument.Tetsuya Yamamoto
The error is due to oledb trying to convert input to a Date. Oledb uses either the JET driver in windows or the ACE driver from Microsoft Office. Oldedb is the default method that is used in Excel and error that you would see in excel when a Cell is set to General Formatting of converting numbers to dates and dates to number are due to the oledb methods. One known issue with oledb is the 1st column it automatically changes dates to integers. So I think your error is due to oledb change 1st column from date to int then failing putting an int into a column in datatable declared as date.jdweng
first column which is read? Or first column of the first table? i read every value with dataRow["some_name"].ToString().Olli
Do you really need to use the OleDb driver to read the csv file into a DataTable? There are other and better options out there for parsing csv files.Rune Grimstad
There are many, but the CsvHelper library is a good place to start. Look at the documentation here: joshclose.github.io/CsvHelper/reading#getting-all-recordsRune Grimstad

1 Answers

1
votes

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.