2017-12-14 52 views
0

私はole-db経由でcsv-dataに接続するアプリケーションを持っています。 csv-dataはデータテーブルにロードされます。次に、テーブルのdatarowsを反復処理します。各データローに対して、関数が呼び出され、データをmysql-dbに挿入します。 csvへのoledbによる例外の奇妙な動作

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); 
} 
+0

'System.ArgumentException'の後にメッセージを翻訳し、' ConvertCSVDocumentRow'メソッドを提供できますか?間違ったメソッド引数を使用している可能性があります。 –

+1

このエラーは、入力を日付に変換しようとしているoledbが原因です。 Oledbは、WindowsのJETドライバまたはMicrosoft OfficeのACEドライバを使用します。 OldedbはExcelで使用されるデフォルトのメソッドで、CellがGeneralに設定されているときExcelに表示されるエラーは、日付と日付の数値を数値に変換するフォーマットはoledbメソッドによるものです。 oledbに関する1つの既知の問題は、自動的に日付を整数に変更する第1列です。だから、私はあなたのエラーは、日付からintにして日付として宣言されたdatatableの列にintを置くことに失敗したから、最初のカラムを変更することによると思います。 – jdweng

+0

最初の列は読み込まれますか?または最初のテーブルの最初の列?私はすべての値をdataRow ["some_name"]で読みます。ToString()。 – Olli

答えて

0

ルーンGrimstadtは、読書のための他のオプションがあります述べたと同様csv-filesをデータセットに追加します。以下は、インターネット上のFileStream i fountのソリューションです:

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; 
} 

これは私のために働いています。