c#使用适配器填充时数据表强制DataType

时间:2016-02-12 19:04:00

标签: c# linq csv datatable

使用OleDbDataAdapter时,我遇到Visual Studio 2010为列选择不正确/不一致DataType的问题。
是否可以将每列的数据类型集中为字符串?
目前我正在尝试将我的CSV文件转换为数据表。当我尝试在相同的列名称上使用相同的方法时,有些列最终会变为double,因此第二个CSV文件以' - '开头,所以它只是假设它是一个字符串)< / p>

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中的相同列是字符串。

如果可能的话,我很乐意把所有这些都集中在字符串上,我会立即转换它们。

感谢。

2 个答案:

答案 0 :(得分:1)

I've posted a class that will read your CSV file for you into a list of CsvLineItem objects. I've shown a couple of different ways to read the values (by column index, or by column name, and how to handle a NULL value)

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

答案 1 :(得分:0)

My suggestion is use an extra step to deal with CSV files that have a harder to read structure. This solution can be used if the file is not huge:

1) Load the CSV in a more friendly structure

Use Microsoft.VisualBasic.FileIO.TextFieldParser to parse all the file and get the data a list of list of strings (or something similar). More details can be found here.

2) While loading the data, convert or skip the values according to your needs.

This solution might be slower, but it gives full control over the parsing.