You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让CSV空值在DataTable中保留为Null以适配SqlBulkCopy

问题:CSV空值转DataTable时变为空字符串导致SqlBulkCopy报错

我使用以下代码在SqlBulkCopy前填充DataTable:

using (StreamReader readerDatatable = new StreamReader(filePath, Encoding.UTF8))
using (CsvReader csvReaderDatatable = new CsvReader(readerDatatable, csvConfig))
using (CsvDataReader dataReader = new CsvDataReader(csvReaderDatatable))
using (var dt = new DataTable())
{
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add("NULL");
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<DateTime?>().NullValues.AddRange(new[] { "NULL", "0", "N/A" });
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<float?>().NullValues.Add("NULL");
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<float?>().NullValues.Add("NA");
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<float?>().NullValues.Add("N/A");
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<decimal?>().NullValues.Add("NULL");
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<decimal?>().NullValues.Add("NA");
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<decimal?>().NullValues.Add("N/A");
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<bool>().BooleanFalseValues.Add("0");
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<bool>().BooleanTrueValues.Add("NA");
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<bool>().BooleanTrueValues.Add("1");

    var bulkCopy = new SqlBulkCopy("Data Source=test;Initial Catalog=test;Trusted_Connection=True;");                         

    dt.Load(dataReader);
}

DataTable已正确填充,但CSV中的空值(如,,)被转换为空字符串(''),执行bulkcopy.WriteToServer时报错(字符串无法转换为实数)。原本以为TypeConverterOptionsCache能解决该问题,但并未生效。请问如何确保CSV中的空值在DataTable中保持为Null?


解决方案
  • 初始化CsvConfiguration时开启空值转换
    CsvHelper默认不会将空字段解析为Null,需在创建CsvReader前配置CsvConfiguration:

    var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
    {
        ConvertEmptyStringToNull = true,
        TrimOptions = TrimOptions.Trim // 可选:去除字段前后空白,避免空白被识别为有效字符串
    };
    
  • 为数值类型添加空字符串到NullValues集合
    针对float?、decimal?等可空数值类型,直接将空字符串加入对应的NullValues,确保空字段被解析为Null:

    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<float?>().NullValues.Add("");
    csvReaderDatatable.Context.TypeConverterOptionsCache.GetOptions<decimal?>().NullValues.Add("");
    
  • 确保DataTable列允许为Null
    检查DataTable中数值类型列的AllowDBNull属性,若列不允许Null,即使解析出Null也会被转为默认值或空字符串:

    foreach (DataColumn col in dt.Columns)
    {
        if (col.DataType == typeof(float) || col.DataType == typeof(decimal))
        {
            col.AllowDBNull = true;
        }
    }
    

内容的提问来源于stack exchange,提问作者Sylvain C.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 08:45:48