问题
I was trying to map a csv file so that each record would simply be a Dictionary<string,object>
.
I am receiving an
ArgumentException "Not a member access;"
When I try to do this. Code included below:
public class CsvFileReader : FileReader
{
public CsvFileReader(string path) : base(path){ }
public IDictionary<string, object> Read()
{
var reader = new CsvReader(new StreamReader(Path));
reader.Read();
reader.Configuration.RegisterClassMap(new DictionaryClassMap(reader.FieldHeaders));
return reader.GetRecord<Dictionary<string, object>>();
}
private class DictionaryClassMap : CsvClassMap<Dictionary<string, object>>
{
private readonly IEnumerable<string> _headers;
public DictionaryClassMap(IEnumerable<string> headers)
{
_headers = headers;
}
public override void CreateMap()
{
foreach (var header in _headers)
{
var localHeader = header;
Map(x => x[localHeader]);
}
}
}
}
回答1:
Unfortunately, there currently is no support for mapping to a Dictionary
.
If you try doing GetRecords<Dictionary<string, object>>()
, you will get an error.
Types that inhererit 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?
You can't map to a Dictionary
either. In a mapping you need to specify a property of the class for the field to be mapped to. The indexer is not a member property which is why you're getting that error.
SOLUTION:
What you CAN do is this:
var record = csv.GetRecord<dynamic>();
You can use it as a dynamic object.
DESIRED SOLUTION
Internally, it uses the ExpandoObject
, so you can do this.
var dict = csv.GetRecord<dynamic>() as IDictionary<string, object>;
回答2:
I was trying to do similar (although not reading all the columns into the Dictionary
, just some). So, in case this is of use, (and strongly aided by this answer) you can have a Dictionary
as a property of a class and then populate that (as Josh say's you can't populate a Dictionary
on it's own as CsvHelper is expecting a member property to map to).
The below would map to a property DictionaryProperty
which is a Dictionary<string,string>
of the class MyClassWithDictionaryMapper
.
public class MyClassWithDictionaryMapper: ClassMap<MyClassWithDictionary>
{
public MyClassWithDictionaryMapper(List<string> headers)
{
Map(m => m.DictionaryProperty).ConvertUsing
(row => headers.Select
(column => new { column, value = row.GetField(column) })
.ToDictionary(d => d.column, d => d.value)
);
}
}
来源:https://stackoverflow.com/questions/21311423/mapping-to-a-dictionary