【问题标题】:Trying to iterate over records from CsvHelper throws ConfigurationException error尝试从 CsvHelper 迭代记录会引发 ConfigurationException 错误
【发布时间】:2019-06-17 09:46:26
【问题描述】:

我正在尝试遍历 .csv 文件以在控制台上输出。我正在使用 CsvHelper 并按照 T 的指南进行操作,但是每当我尝试遍历从 GetRecords() 方法获得的 IEnumerable 时,就会出现 ConfigurationException。

这是我正在使用的代码

using (var reader_ans = new StreamReader("scriptlists/prac_iden_ans.csv"))
using (var csv_ans = new CsvReader(reader_ans))
{
    var ans = csv_ans.GetRecords<string>();

    foreach (string item in ans)
    {
        Debug.Log(item);
    }
}

这很奇怪,因为这正是文档和多个网站中的内容。

出现的错误是这样的:

ConfigurationException: Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?

我想知道这是否是我错过的一些愚蠢的事情,因为我对 C# 还很陌生。我也在 Unity3D 中对此进行编码,所以这可能是问题的一部分吗?

我也尝试在第一行使用 .ToList() 方法,但无济于事。


编辑1:

在尝试创建自定义类后,我遇到了另一个错误,这次是在我运行代码之前来自编译器。

本质上,在这个sn-p的代码中:

foreach (string item in ans)
            {
                Debug.Log(item);
            }

foreach 被突出显示,并显示一条错误消息“无法将类型 'instructions.ScriptsList' 转换为 'string'”。我的文件名为“instructions.cs”。

还有一些可能是问题的额外信息:

1) 我在 IEnumerator 中编写这段代码,但我认为这不是问题,因为我确实有其他“foreach”行。除非 CsvHelper 使用某些在 IEnumerator 中不起作用的代码?

2) 我的 .csv 文件是在 excel 中创建的,并且它们确实有标题。它实际上只是多列“是”和“否”。在 Excel 中创建它并将其保存为 .csv(逗号分隔)是否会影响 CsvHelper 读取它的方式?

3) 类写在这个函数之上有关系吗? (我知道这是一种基础,但我对 C# 还是很陌生,而且我注意到在很多文档中,该类通常写在函数下方)

非常感谢您的帮助!

【问题讨论】:

  • example 指出,你需要一个 Foo 类
  • 你的第一列是数字吗? csvHelper 使用的是 Jet Engine,它是 Excel 和 Access 的驱动程序。当数字是行号而不是列数据时,Jet 引擎假定第一列。因此,所有其他列都会移动到比您预期低一的索引。在 Excel 中使用通用格式也是同样的问题,它试图猜测数据类型并经常将数字更改为日期,将日期更改为数字。微软试图将智能添加到他们经常出错的软件中。
  • Debug.Log() 正在寻找一个字符串,而您正在给它一个 instructions.ScriptsList 对象。
  • @DavidSpecht Debug.Log 接受 object 并对其执行 ToString。喂它什么都没关系。

标签: c# unity3d automapper ienumerable csvhelper


【解决方案1】:

您收到的错误消息是指无法使用给定配置填充。

你想给GetRecords&lt;&gt; 一个类或结构,它将用你的.csv 中每一行的值填充。您的脚本可能由于尝试将一行填充到 string 类型而失败。

示例解决方案,鉴于您的 .csv 看起来与此类似:

您的prac_iden_ans.csv 文件:

Path
C:/example/path/one
C:/example/path/two

您的.cs C# 脚本文件:

void YourFunction() {

    using (var reader_ans = new StreamReader("scriptlists/prac_iden_ans.csv"))
    using (var csv_ans = new CsvReader(reader_ans))
    {
        var ans = csv_ans.GetRecords<ScriptsList>();

        foreach (ScriptsList item in ans)
        {
            Debug.Log(item.Path);
        }
    }

}

class ScriptsList {
    public string Path { get; set; }
}

但是,如果您的 .csv 文件缺少标题行(即第一行指定每列代表的内容),您可以将 CsvReader 配置为不需要标题行。但是,您必须以不同的方式告诉CsvReader 哪些列映射到哪些属性。一种方法是IndexAttribute。示例:

您的prac_iden_ans.csv 文件:

C:/example/path/one
C:/example/path/two

您的.cs C# 脚本文件:

void YourFunction() {

    using (var reader_ans = new StreamReader("scriptlists/prac_iden_ans.csv"))
    using (var csv_ans = new CsvReader(reader_ans))
    {
        csv_ans.Configuration.HasHeaderRecord = false;
        var ans = csv_ans.GetRecords<ScriptsList>();

        foreach (ScriptsList item in ans)
        {
            Debug.Log(item.Path);
        }
    }

}

class ScriptsList {
    [Index(0)]
    public string Path { get; set; }
}

但如果您只是逐行读取文件中的每一行,我建议您只使用StreamReader、File.OpenRead 或简单的File.ReadAllLines。示例:

您的prac_iden_ans.csv 文件:

C:/example/path/one
C:/example/path/two

您的.cs C# 脚本文件:

string[] ans = File.ReadAllLines("scriptlists/prac_iden_ans.csv");

foreach (string item in ans)
{
    Debug.Log(item);
}

【讨论】:

  • 不幸的是,我不能使用您的第三个建议,因为我在 .csv 文件中有多个列,尽管它是一个很好的供将来参考的列。我的 .csv 确实有一个标题。我刚刚尝试创建一个自定义类,但似乎又出现了另一个问题。我将在编辑中显示它。
【解决方案2】:

对于您更新的问题:

  1. 这是我的错字。忘记将 foreach 项目变量从 string 更改为 ScriptsList。我已经更新了我的答案。你的 sn-p 应该是:
foreach (ScriptsPath item in ans)
{
    Debug.Log(item);
}
  1. 没有。没有区别。唯一需要注意的是,.csv 有时会使用分号 ; 而不是逗号 , 作为分隔符来格式化。但是.csv 是最基本的格式之一

  2. 没有。如果它占用相同的文件/示例,则在文件底部和类下方编写class、struct 和enum 是一种常见的约定。它是 C# 语法的一部分,C# 编译器不需要类型定义的特定位置。这与您在自上而下的方法中编写的代码不同,而类型定义遵循更广泛的树状结构。

    您用 C# 编写的代码流只是 C# 完整语法的一部分。在我看来,C# 的强大之处在于其语法的其余部分,包括命名空间、属性、枚举器方法、可访问性修饰符等。

【讨论】:

  • 哦,是的。感谢您的所有帮助和建议! (:
猜你喜欢
  • 2019-09-07
  • 2020-06-28
  • 2014-02-03
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多