web-dev-qa-db-ja.com

CsvHelper:タイプにマップされているメンバーはありません

CsvHelper 4.0. を使用します。

私はnestedクラスを次のように定義しています:

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>();

ドキュメントによると ここ 、上記のコードは機能するはずです。

ただし、recordsを調べると、No members are mapped for type 'ParentClass+CsvLine'というメッセージが表示されます。

CsvLineのアクセシビリティをprivateからpublicに変更しましたが、違いはありませんでした。

私は何を間違えましたか?

EDIT:CsvLineクラスのネストを解除して公開しようとしましたが、それも役に立ちませんでした。

編集:私は Nkosiが提案 ;として変更を加えました。ただし、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 ' 答えはお互いを補完します。

7
MY_G

デフォルトでは、オブジェクトモデルのフィールドの代わりにプロパティを使用する必要があります。これにより、一致するパブリックメンバーがマップされます。

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:クラスマッピング

11
Nkosi

Nkosiは、CsvHelperはデフォルトでプロパティにマップされると説明しました。

過去にデバッガーで_Enumeration yielded no results_メッセージに遭遇しました。メッセージは誤解を招くものです。デバッガーがレコードがないと言っていても、areレコードがあります。 foreachを使用してIEnumerableを反復処理するか、.ToArray()または.ToList()を呼び出して、すべてのレコードをロードします。例:

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

または

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

resultsフォーマット指定子 を追加することにより、デバッガーにWatch、Quick Watch、またはImmediateウィンドウのIEnumerableにすべてのアイテムを表示させることができます。例:

_records,results
_

これによりIEnumerableが実行され、すべての結果が返されるため、注意してください。

これと他のトリックは Visual Studio 2017の7つの隠された宝石 で見つけることができます

6

その他の考えられる原因:

  • ヘッダー文字列の引用文字。
  • 区切り文字。

それらを構成するためのサンプルコード:

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

この問題にはもっと簡単な解決策があります。それはたった1行のコードです。 csvhelperにフィールドを確認するように指示する必要があります。

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

CsvHelper 12.2.2の時点で、これは私がそれを機能させるためにしなければならなかったことです

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

CsvReaderのドキュメントにも関わらず、何らかの理由で、Read()メソッドとReadHeader()メソッドを追加すると、実際にcsvファイルからデータを取得できるようになります。

0
kyle_l