【问题标题】:CsvHelper: No members are mapped for typeCsvHelper:没有为类型映射成员
【发布时间】:2017-11-01 15:34:50
【问题描述】:

我使用CsvHelper 4.0.3

我有一个这样定义的嵌套类:

private class CsvLine {
    public string Solution;
    public string Project;
    public string DependsOnProject;
    public string Weight;
    public string DependsOnPackage;
    public string PackageVersion;
}

我想使用 CsvHelper 解析的 .csv 文件具有以下字段名称:

Solution,Project,DependsOnProject,Weight,DependsOnPackage,PackageVersion

这是我的代码:

TextReader readFile = new StreamReader(dependenciesCsvFilePath);
var csvReader = new CsvReader(readFile);
IEnumerable<CsvLine> records = csvReader.GetRecords<CsvLine>();

根据文档here,上面的代码应该可以工作。

但是,当我检查 records 时,我看到了消息 No members are mapped for type 'ParentClass+CsvLine'

我将CsvLine 的可访问性从private 更改为public,但这并没有什么不同。

我做错了什么?

编辑:我尝试取消嵌套 CsvLine 类并将其公开,但这也无济于事。

编辑:我以Nkosi suggested 进行了更改;但是,现在它说records 是一个空集合:“枚举没有产生任何结果”。我的 .csv 文件中肯定存在数据,因此集合不应为空。

以下是一些示例数据:

Solution,Project,DependsOnProject,Weight,DependsOnPackage,PackageVersion
FOD.sln,ABC.DEF,IMS.ABC,1,,
FOD.sln,ABC.DEF,IMS.DEF,1,,
FOD.sln,ABC.DEF,IMS.GHI,1,,
FOD.sln,ABC.DEF,IMS.JKL,1,,

编辑:已解决! Nkosi'sPanagiotis' 的答案相互补充。

【问题讨论】:

  • 未嵌套时同样的错误?
  • 字段与属性。
  • 文件中的标题在哪里?如果没有标题,那么您将必须创建一个类映射以按索引映射
  • 使用.GetRecords&lt;CsvLine&gt;().ToArray()先加载数据,然后检查。即使有记录,我也看到调试器抱怨空枚举。顺便说一句,您使用的是哪个版本的 CsvHelper?它几乎每周都会更改版本
  • @PanagiotisKanavos 调用 ToArray() 成功了。谢谢!

标签: c# csvhelper


【解决方案1】:

默认情况下,您需要使用属性而不是对象模型中的字段,它将映射匹配的公共成员

public class CsvLine {
    public string Solution { get; set; }
    public string Project { get; set; }
    public string DependsOnProject { get; set; }
    public string Weight { get; set; }
    public string DependsOnPackage { get; set; }
    public string PackageVersion { get; set; }
}

您还应该阅读有关将类映射到 csv 文件的内容。

CsvHelper: Class Mapping

【讨论】:

  • 感谢您的回复!我按照您的建议进行了更改;但是,现在它说 records 是一个空集合:“枚举没有产生任何结果”。我的 .csv 文件中肯定存在数据,因此集合不应为空。
  • 我有与@my_g 相同的症状,并通过将所有属性上的私有设置器更改为公共设置器来解决它。
  • 截至 2020 年 1 月,课程映射链接为 404 not found。请转至此处:joshclose.github.io/CsvHelper/…
  • @LeonardAB 我修复了链接。感谢您的提醒。
  • 注意@robin-qiu 回答
【解决方案2】:

Nkosi 解释说 CsvHelper 默认映射到属性。

我过去在调试器中遇到过Enumeration yielded no results 消息。该消息具有误导性。 条记录,即使调试器说没有。您使用foreach 迭代IEnumerable 或调用.ToArray().ToList() 以加载所有记录,例如:

var records = csvReader.GetRecords<CsvLine>();
foreach(var record in records)
{
     ...
}

或者

var records = csvReader.GetRecords<CsvLine>().ToArray();

您可以通过添加results format specifier 来强制调试器在 Watch、Quick Watch 或 Immediate 窗口中显示 IEnumerable 中的所有项目,例如:

records,results

小心,因为这将执行 IEnumerable 并返回所有结果。

你可以在7 Hidden Gems in Visual Studio 2017找到这个以及其他技巧

【讨论】:

  • 谢谢你!我试图查看 QuickWatch 中的结果对象,但它说“枚举没有结果”。添加 foreach 后,我可以检查每条记录。谢谢! var 记录 = csv.GetRecords(); foreach(var record in records) { string recordObject = JsonConvert.SerializeObject(record); }
【解决方案3】:

其他可能的原因:

  • 标题字符串引号字符。
  • 分隔符。

配置它们的示例代码:

var conf = new CsvHelper.Configuration.Configuration();
conf.Delimiter = ",";
conf.Quote = '\'';
var csv = new CsvHelper.CsvReader(reader, conf);
var rows = csv.GetReads<MyClass>();

【讨论】:

  • 我遇到了同样的问题,即使在添加了 ClassMap 之后也是如此。分隔符也涉案!
【解决方案4】:

这个问题有一个更简单的解决方案,它只有一行代码。您必须告诉 csvhelper 查看您的字段。

using (var csv = new CsvWriter(writer))
{
    csv.Configuration.MemberTypes = CsvHelper.Configuration.MemberTypes.Fields;
.....
}

【讨论】:

  • MemberTypes 现在是只读的
【解决方案5】:

从 CsvHelper 12.2.2 开始,我必须这样做才能让它工作

csv.Read() 
csv.ReadHeader()
csv.GetRecords<T>().ToList();

尽管有 CsvReader 的文档,但出于某种原因,添加 Read() 和 ReadHeader() 方法将使它真正从 csv 文件中提取数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多