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

使用CsvHelper读取CSV时无法将科学计数法值转换为Int64

包含科学计数法格式Call_ID列的CSV文件

问题场景

现有CSV文件中Call_ID列的值以科学计数法格式存储(例如3.08E+12),需要将该列的长整型数值以Int64类型读取后存入列表,初始读取逻辑如下:

List<Model> result = null;
using (StreamReader streamReader = new StreamReader(_excelFileConfiguration.Path + fileName))
{
    var csv = new CsvReader(streamReader, CultureInfo.InvariantCulture);
    csv.Context.RegisterClassMap<TestMap>();
    result = csv.GetRecords<Model>().ToList();
}

初始定义的模型类与映射类如下:

public class Model
{
  public int AccountId { get; set; }
  // 注意:原代码写的小写int64是C#语法错误,64位整型正确写法为long(对应System.Int64)
  public long CallId { get; set; }
  public DateTime Date { get; set; }
}
public sealed class TestMap : ClassMap<Model>
{
    public TestMap()
    {
        Map(m => m.AccountId).Name("accountID");
        Map(m => m.CallId).Name("Call_ID");
        Map(m => m.Date).Name("Date");
    }
}

运行上述代码时抛出转换错误:The conversion cannot be performed. Text: '3.08E+12',默认转换器无法直接将科学计数法格式的字符串转为Int64类型。

解决方法

报错核心原因是CsvHelper内置的Int64类型转换器不支持直接解析科学计数法格式的数字字符串,通过自定义类型转换器即可解决,完整实现步骤如下:

  • 编写自定义长整型转换器,兼容科学计数法格式解析
using CsvHelper;
using CsvHelper.TypeConversion;
using System.Globalization;

public class ScientificNotationToLongConverter : DefaultTypeConverter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        if (string.IsNullOrWhiteSpace(text))
            return 0L;
        // 优先解析科学计数法格式,转为double后再转long
        if (double.TryParse(text, NumberStyles.Float | NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out double tempValue))
        {
            return Convert.ToInt64(tempValue);
        }
        // 兼容普通整数字符串格式
        return long.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out long longValue) 
            ? longValue 
            : base.ConvertFromString(text, row, memberMapData);
    }
}
  • 在类映射配置中,为CallId字段绑定上述自定义转换器
public sealed class TestMap : ClassMap<Model>
{
    public TestMap()
    {
        Map(m => m.AccountId).Name("accountID");
        Map(m => m.CallId).Name("Call_ID").TypeConverter<ScientificNotationToLongConverter>();
        Map(m => m.Date).Name("Date");
    }
}

如果不想单独定义转换器类,也可以直接在映射时写内联转换逻辑,效果完全一致:

public sealed class TestMap : ClassMap<Model>
{
    public TestMap()
    {
        Map(m => m.AccountId).Name("accountID");
        Map(m => m.CallId).Name("Call_ID").Convert(row =>
        {
            var text = row.GetField("Call_ID");
            if (double.TryParse(text, NumberStyles.Float | NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out double temp))
            {
                return Convert.ToInt64(temp);
            }
            return 0L;
        });
        Map(m => m.Date).Name("Date");
    }
}

注意:如果Call_ID的数值超过long类型最大值(9223372036854775807),需要改用ulong或者字符串类型存储,避免数值溢出。

内容的提问来源于stack exchange,提问作者nagaraj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.20 16:15:51