2016-02-12 57 views
0

我在使用OleDbDataAdapter时遇到Visual Studio 2010在为列选择不正确/不一致DataType的问题。
是否有可能将每列的数据类型设置为字符串?
当前我试图将我的CSV文件转换为Datatable。当我尝试在相同的列名上使用相同的方法时,其中一些列最终变成了双倍字符串(因为第二个CSV文件以' - '符号开始,所以它只是假设它是一个字符串)c#使用适配器填充时的数据表强制DataType

using (OleDbConnection connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Path.GetDirectoryName(filePath) + ";Extended Properties=\"Text;HDR=Yes;TypeGuessRows=0;ImportMixedTypes=Text\"")) 
using (OleDbCommand command = new OleDbCommand(@"SELECT * FROM [" + Path.GetFileName(filePath) + "]", connection)) 
using (OleDbDataAdapter adapter = new OleDbDataAdapter(command)) 
adapter.Fill(dt); 

尝试与另一csv文件进行合并:

using (OleDbConnection connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Path.GetDirectoryName(part2FilePath) + ";Extended Properties=\"Text;HDR=Yes;TypeGuessRows=0;ImportMixedTypes=Text\"")) 
using (OleDbCommand command = new OleDbCommand(@"SELECT * FROM [" + Path.GetFileName(part2FilePath) + "]", connection)) 
using (OleDbDataAdapter adapter = new OleDbDataAdapter(command)) 
{ 
    DataTable tmpDt = new DataTable(); 
    adapter.Fill(tmpDt); 
    dt.Merge(tmpDt, true, MissingSchemaAction.Add); 
} 

我碰到这种冲突的数据类型不匹配。第一个CSV具有双列作为列中的一个,但第二个CSV中的同一列以字符串形式出现。

如果可能,我很乐意把他们都集中在字符串,我会在飞行中转换它们。

谢谢。

+0

试着看看这个链接http://stackoverflow.com/questions/1050112/how-to-read-a-csv-file-into-a-net-datatable如果听起来不像你需要创建一个空的例如一个数据表,并添加列/类型像这样'table11.Columns.Add(“ID”,typeof(double));'例如,然后填充数据表以这种方式尝试这个以及它工作顺便http:// stackoverflow.com/questions/3306330/creating-a-datatable-from-csv-file – MethodMan

+0

尝试使用List 并使用循环和OleDbDataReader将CSV读入该列表。 reader = command.ExecuteReader(); while(reader.Read()){items.Add(new YourCsvSchema(reader.GetDouble(0))); ....}读者可以更好地控制如何读取和转换值。 – Mangist

+0

@Mangist这听起来很聪明。所以我创建了一个类即ie。 'class CsvSchema {public string Name {get; set;} public double Value {get;设置;}}'然后通过阅读器循环添加项目...只是有点困惑如何设置标题名称与正确的CsvSchema对象。即如何将[Name]设置为Name对象,将[Value]设置为Value对象。你可以写一个简单的解决方案,它可以解决这个问题。谢谢。 –

回答

1

我已经发布了一个类,可以将您的CSV文件读入CsvLineItem对象列表。我已经展示了几个不同的方式来读取值(由列索引,或者列名,以及如何处理空值)

public class CsvLineItem 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public double Value1 { get; set; } 
    public double Value2 { get; set; } 
} 
public static class CsvReader 
{ 
    public static IList<CsvLineItem> Read(string csvFilename) 
    { 
     var items = new List<CsvLineItem>(); 

     using (var connection = new OleDbConnection(
      @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" 
       + Path.GetDirectoryName(csvFilename) 
       + ";Extended Properties=\"Text;HDR=Yes;TypeGuessRows=0;ImportMixedTypes=Text\"")) 
     { 
      connection.Open(); 

      using (var command = new OleDbCommand(@"SELECT * FROM [" + Path.GetFileName(csvFilename) + "]", connection)) 
      { 
       using (var reader = command.ExecuteReader()) 
       { 
        while (reader.Read()) 
        { 
         items.Add(new CsvLineItem 
         { 
          Id = reader.GetInt32(0), // By column index 
          Name = reader.GetString(reader.GetOrdinal("Name")), // By column name 
          Value1 = reader.GetDouble(2), 
          Value2 = reader.IsDBNull(3) ? 0 : reader.GetDouble(3) // Handling nulls 
         }); 
        } 
       } 
      } 
     } 

     return items; 
    } 
+0

哇,这太神奇了。是的,我明白了逻辑。做得好!非常感谢! –

0

我的建议是使用一个额外的步骤来处理CSV文件阅读结构难以理解。该解决方案可用于如果文件不是很大:

1)根据CSV更友好的结构

使用Microsoft.VisualBasic.FileIO.TextFieldParser解析所有文件并获取数据的字符串列表清单(或类似的东西)。更多细节可以在here找到。

2)在加载数据时,根据需要转换或跳过这些值。

该解决方案可能会比较慢,但它可以完全控制解析。

相关问题