阅读时CSV文件使用数据读取器和OLEDB喷数据提供者,如何才能控制列数据的类型?
题
在我的C#用我的使用微软喷OLEDB数据提供者阅读CSV文件。连串这样的:
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\Data;Extended Properties="text;HDR=Yes;FMT=Delimited
我打开一个ADO.NET OleDbConnection使用这一连串和选择的所有行CSV文件的命令:
select * from Data.csv
当我打开一个OleDbDataReader和检查的数据类型列返回,我找到那东西堆试图猜测的数据类型,根据第一行中的数据文件。例如,假设CSV文件包含:
House,Street,Town
123,Fake Street,Springfield
12a,Evergreen Terrace,Springfield
叫OleDbDataReader.GetDataTypeName方法对于家列将揭示该列已经给出的数据类型"DBTYPE_I4",所以所有数值读它被解释为整数。我的问题是这房子应该是一串-当我试图阅读的房子值从第二行,OleDbDataReader返回空。
我怎么能告诉任何喷数据库的供应商或OleDbDataReader解释列为串而不是数字?
解决方案
有一个模式文件您可以创建,这将告诉ADO.NET 如何解释CSV效,给予它一种结构。
试试这个: http://www.aspdotnetcodes.com/Importing_CSV_Database_Schema.ini.aspx
其他提示
扩大在马克的答案,我需要建立一个文本文件被称为模式。ini,并把它放在同一个目录中的CSV文件。以及列类型,这个文件可以规定格式的文件,日期间的格式、区域设置和列名如果他们不包括在该文件。
让我给的例子,在这个问题的工作,方案文件应该是这样的:
[Data.csv]
ColNameHeader=True
Col1=House Text
Col2=Street Text
Col3=Town Text
我也可以试试这个,使数据提供者检查中的所有行文件之前,它试图猜测的数据类型:
[Data.csv]
ColNameHeader=true
MaxScanRows=0
在现实生活中,我的申请进口数据文件动态的名字,所以我必须创建一种架构。ini文件,并写入其向相同的目录中CSV文件之前,我打开了我的连接。
进一步的细节可以在这里找到- http://msdn.microsoft.com/en-us/library/ms709353(VS。85).aspx -或通过搜索MSDN Library for"架构。ini文件"。
请检查
using (var reader = new CsvReader("data.csv"))
{
reader.ReadHeaderRecord();
foreach (var record in reader.DataRecords)
{
var name = record["Name"];
var age = record["Age"];
}
}
你需要告诉司机要扫描的所有行确定的模式。否则,如果一些行的数字,其余的都是字母数字、字母细胞将空白。
喜欢 Rory, 我发现我需要创建一种架构。ini文件动态的,因为没有办法通过程序告诉司机要扫描的所有行。(这个不是这种情况的excel文件)
你必须 MaxScanRows=0
在你的架构。ini
这里的代码实例:
public static DataTable GetDataFromCsvFile(string filePath, bool isFirstRowHeader = true)
{
if (!File.Exists(filePath))
{
throw new FileNotFoundException("The path: " + filePath + " doesn't exist!");
}
if (!(Path.GetExtension(filePath) ?? string.Empty).ToUpper().Equals(".CSV"))
{
throw new ArgumentException("Only CSV files are supported");
}
var pathOnly = Path.GetDirectoryName(filePath);
var filename = Path.GetFileName(filePath);
var schemaIni =
$"[{filename}]{Environment.NewLine}" +
$"Format=CSVDelimited{Environment.NewLine}" +
$"ColNameHeader={(isFirstRowHeader ? "True" : "False")}{Environment.NewLine}" +
$"MaxScanRows=0{Environment.NewLine}" +
$" ; scan all rows for data type{Environment.NewLine}" +
$" ; This file was automatically generated";
var schemaFile = pathOnly != null ? Path.Combine(pathOnly, "schema.ini") : "schema.ini";
File.WriteAllText(schemaFile, schemaIni);
try
{
var sqlCommand = $@"SELECT * FROM [{filename}]";
var oleDbConnString =
$"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={pathOnly};Extended Properties=\"Text;HDR={(isFirstRowHeader ? "Yes" : "No")}\"";
using (var oleDbConnection = new OleDbConnection(oleDbConnString))
using (var adapter = new OleDbDataAdapter(sqlCommand, oleDbConnection))
using (var dataTable = new DataTable())
{
adapter.FillSchema(dataTable, SchemaType.Source);
adapter.Fill(dataTable);
return dataTable;
}
}
finally
{
if (File.Exists(schemaFile))
{
File.Delete(schemaFile);
}
}
}
你只需要做一些修改,如果你正在运行这一相同的目录中的多线程的同时。