映射到字典

4
我试图将一个csv文件映射成每个记录只是一个Dictionary<string,object>的形式。
但是我收到了一个参数异常“Not a member access;”。
下面是我的代码:
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]);
            }
        }
    } 
}
2个回答

13

很遗憾,目前不支持将映射到Dictionary

如果您尝试执行GetRecords<Dictionary<string, object>>(),将会收到错误信息。

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?

您也不能将其映射到 Dictionary。在映射中,您需要指定类的属性以便将字段映射到该属性。索引器不是成员属性,这就是为什么您会收到该错误的原因。

解决方案:

您可以这样做:

var record = csv.GetRecord<dynamic>();

你可以将其用作动态对象。

期望的解决方案

它在内部使用ExpandoObject,因此你可以这样做。

var dict = csv.GetRecord<dynamic>() as IDictionary<string, object>;

1

我试图做类似的事情(虽然不是将所有列读入 Dictionary,只是一些)。所以,如果有用的话(并且受到 this answer 的强烈帮助),你可以将一个 Dictionary 作为类的属性,然后填充它(正如 Josh 所说,你不能单独填充一个 Dictionary,因为 CsvHelper 期望一个成员属性进行映射)。

下面的代码将映射到一个名为 DictionaryProperty 的属性,它是类 MyClassWithDictionaryMapperDictionary<string,string> 类型。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接