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

CsvHelper CsvClassMap映射数组成员报Not a member access错误求助

CsvHelper映射数组字段报错解决方案

(更新版本)使用CsvHelper的CsvClassMap从CSV文件读取日期数据时,映射数组成员运行抛出错误:Not a member access Parameter name: expression。

原实现代码

主读取逻辑

void Main()
{
    using (var reader = new StreamReader("path\\to\\file.csv"))
    using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
    {       
        csv.Context.RegisterClassMap<LoanRecord>();
        var records = csv.GetRecords<LoanRecord>();
    }
}

public class LoanRecord : Model
{
    public LoanRecord()
    {
    }
    public string[] LoanStart_DateTime = new string[2];
    public string[] LoanEnd_DateTime = new string[2];
}

原映射类代码

public sealed class LoanMapper: CsvClassMap<LoanRecord>
{
    public LoanMapper()
    {
        Map(m => m.LoanStart_DateTime[0]).Index(0);
        Map(m => m.LoanEnd_DateTime[0]).Index(1);
        Map(m => m.LoanStart_DateTime[1]).Index(2);
        Map(m => m.LoanEnd_DateTime[1]).Index(3);
    }
}

对应CSV格式

LoanStart_DateTime1,LoanEnd_DateTime1,LoanStart_DateTime2,LoanEnd_DateTime2
01/12/2022 00:00,02/12/2022 00:00,23/05/2022 00:00,23/05/2022 03:00,

错误原因

  • CsvHelper默认Map方法的表达式解析逻辑仅支持直接映射类的公开属性/字段,不支持数组索引器这类带参数的成员访问写法,传入数组索引访问表达式时会直接抛出参数错误。
  • 主逻辑存在笔误:RegisterClassMap泛型参数传入的是实体类LoanRecord,而非自定义的映射类LoanMapper,映射规则本身不会生效。

解决方法

  • 方法1:改用独立属性映射(推荐,实现最简单)
    放弃数组存储结构,为每个CSV列定义独立的公开属性,完全符合CsvHelper默认映射规则:

    public class LoanRecord : Model
    {
        // 第一组日期字段,对应CSV前两列
        public string LoanStart_DateTime1 { get; set; }
        public string LoanEnd_DateTime1 { get; set; }
        // 第二组日期字段,对应CSV后两列
        public string LoanStart_DateTime2 { get; set; }
        public string LoanEnd_DateTime2 { get; set; }
    }
    
    public sealed class LoanMapper: CsvClassMap<LoanRecord>
    {
        public LoanMapper()
        {
            Map(m => m.LoanStart_DateTime1).Index(0);
            Map(m => m.LoanEnd_DateTime1).Index(1);
            Map(m => m.LoanStart_DateTime2).Index(2);
            Map(m => m.LoanEnd_DateTime2).Index(3);
        }
    }
    

    读取完成后如果需要数组结构,在业务代码中手动赋值即可,同时需要修正主逻辑中注册映射的笔误,将RegisterClassMap<LoanRecord>()改为RegisterClassMap<LoanMapper>()。

  • 方法2:使用ConvertUsing自定义赋值逻辑
    如果必须保留数组字段结构,可以通过ConvertUsing方法手动从行数据中取值赋值,不需要走默认的成员表达式解析:

    public sealed class LoanMapper: CsvClassMap<LoanRecord>
    {
        public LoanMapper()
        {
            Map(m => m.LoanStart_DateTime).Convert(row =>
            {
                return new string[2]
                {
                    row.Row.GetField(0),
                    row.Row.GetField(2)
                };
            });
            Map(m => m.LoanEnd_DateTime).Convert(row =>
            {
                return new string[2]
                {
                    row.Row.GetField(1),
                    row.Row.GetField(3)
                };
            });
        }
    }
    

    该方法同样需要先修正注册映射类的笔误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:46:03