【发布时间】:2019-02-06 00:20:21
【问题描述】:
在将 CSV 读入 DataTable 时,我正在尝试为似乎不起作用的布尔值和空值添加选项。例如,包含类似于以下数据的文件:
Id,MaxDiscount,Name,Active,AltId
1,,Foo,1,ABC123
2,10,Bar,0,DEF345
以及以下使用模式文件动态获取我们期望的标头和数据类型的逻辑:
var dt = new DataTable();
using (var reader = new StreamReader(file.FullName))
using (var csv = new CsvReader(reader))
{
csv.Configuration.HasHeaderRecord = true;
csv.Configuration.IgnoreQuotes = false;
csv.Configuration.TypeConverterOptionsCache.GetOptions<int>().NullValues.Add(string.Empty);
csv.Configuration.TypeConverterOptionsCache.GetOptions<bool>().BooleanFalseValues.Add("0");
csv.Configuration.TypeConverterOptionsCache.GetOptions<bool>().BooleanTrueValues.Add("1");
using (var dr = new CsvDataReader(csv))
{
foreach (var p in schema.Properties)
{
var type = Type.GetType(p.Type, true, true);
var dc = new DataColumn
{
ColumnName = p.Name,
Unique = p.IsId,
AllowDBNull = p.Nullable,
DataType = type
};
dt.Columns.Add(dc);
}
dt.Load(dr);
}
}
这会导致错误String was not recognized as a valid Boolean. Couldn't store <0> in Active Column. Expected type is Boolean.
如果我手动更改数据并将0 替换为false 并将1 替换为true,则布尔值有效,但出现类似错误:Input string was not in a correct format. Couldn't store <> in MaxDiscount Column. Expected type is Int32.
为了让它发挥作用,我这里有什么遗漏吗?还是类型转换器选项仅适用于已知对象?
编辑:
在解析 CSV 文件时,我无法使用任何预定义的对象模型,因为它们可以包含任意数量的字段。只要存在模式,程序就应该知道如何处理它。示例模式如下所示:
{
"type": "Part",
"bucket": "s3Bucket",
"prefix": "prefix/of/datafile",
"targetDirectory": "..\\path\\to\\working\\dir",
"delimiter": ",",
"properties": [
{
"name": "Id",
"type": "System.String",
"required": true,
"nullable": false,
"isId": true,
"defaultValue": null,
"minLength": 6,
"maxLength": 8
},
{
"name": "MaxDiscount",
"type": "System.Int32",
"required": true,
"nullable": true,
"isId": false,
"defaultValue": null,
"minLength": -1,
"maxLength": -1
},
{
"name": "Name",
"type": "System.String",
"required": true,
"nullable": false,
"isId": false,
"defaultValue": null,
"minLength": 1,
"maxLength": 127
},
{
"name": "Active",
"type": "System.Boolean",
"required": true,
"nullable": false,
"isId": false,
"defaultValue": null,
"minLength": 1,
"maxLength": 1
},
{
"name": "AltId",
"type": "System.String",
"required": true,
"nullable": true,
"isId": false,
"defaultValue": null,
"minLength": 1,
"maxLength": 127
}
]
}
在这种情况下,架构中的 Properties 将与 CSV 文件中的列相关。理论上,这将允许我在运行时解析文件并验证数据类型,而不必在每次引入新的 CSV 布局时创建新的对象模型。
【问题讨论】:
-
schema在哪里/如何定义? -
如果您使用可空的 int 版本
GetOptions<int?>()而不是不可空的版本会怎样? -
@grek40 模式是从一个 JSON 文件中解析出来的,该文件包含有关正在读取的 CSV 的信息。当我使用可为空的 int 选项时,我得到完全相同的错误
-
您能发布您的架构信息吗?
-
@WaelAbbas Schema 信息已发布,谢谢!