Сопоставление со словарем

Я пытался сопоставить файл csv, чтобы каждая запись была просто Dictionary<string,object>.

я получаю

ArgumentException "Не членский доступ;"

Когда я пытаюсь это сделать. Код включен ниже:

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

person Matt    schedule 23.01.2014    source источник


Ответы (2)


К сожалению, в настоящее время нет поддержки сопоставления с 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>;
person Josh Close    schedule 10.04.2014

Я пытался сделать подобное (хотя и не читал все столбцы в Dictionary, а только некоторые). Итак, в случае, если это полезно (и сильно помогает этот ответ), вы можете иметь Dictionary как свойство class, а затем заполните его (как говорит Джош, вы не можете заполнить Dictionary самостоятельно, поскольку CsvHelper ожидает, что свойство члена будет отображаться).

Приведенное ниже будет отображаться на свойство DictionaryProperty, которое является Dictionary<string,string> класса 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)
            );
    }
}
person d219    schedule 20.05.2020