oledb 到 csv 异常的奇怪行为
Strange behavior of exception with oledb to csv
我有一个应用程序,它通过 ole-db 连接到 csv-data。 csv 数据被加载到数据 table 中。然后我遍历 table 的数据行。对于每个数据行,都会调用一个函数,该函数将数据插入 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}");
}
}
当我执行此代码时,在创建我的数据集的行上抛出异常 (using var dataSet = base.Source.CreateDataSet())
我收到以下消息:
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.
当我注释掉行时 this.ConvertCSVDocumentRow(dataTable.Rows[i]);
没有抛出异常,并且通过数据行的迭代成功。
有人可以解释一下发生了什么吗?错误发生在该行甚至被调用之前,当抛出异常时,这个函数甚至还没有被调用。
#
以下是我创建数据集的方式:
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;
}
}
这是 ConvertSCVDocumentRow 函数的抽象版本:
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);
}
就像 Rune Grimstadt 提到的那样,还有其他选项可以将 csv 文件读取到数据集。这是我在互联网上找到的 FileStream 的解决方案:
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;
}
这对我有用。
我有一个应用程序,它通过 ole-db 连接到 csv-data。 csv 数据被加载到数据 table 中。然后我遍历 table 的数据行。对于每个数据行,都会调用一个函数,该函数将数据插入 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}");
}
}
当我执行此代码时,在创建我的数据集的行上抛出异常 (using var dataSet = base.Source.CreateDataSet())
我收到以下消息:
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.
当我注释掉行时 this.ConvertCSVDocumentRow(dataTable.Rows[i]);
没有抛出异常,并且通过数据行的迭代成功。
有人可以解释一下发生了什么吗?错误发生在该行甚至被调用之前,当抛出异常时,这个函数甚至还没有被调用。
#以下是我创建数据集的方式:
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;
}
}
这是 ConvertSCVDocumentRow 函数的抽象版本:
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);
}
就像 Rune Grimstadt 提到的那样,还有其他选项可以将 csv 文件读取到数据集。这是我在互联网上找到的 FileStream 的解决方案:
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;
}
这对我有用。