首页 > 解决方案 > 使用 csvhelper 将带有嵌套字典的类写入 csv,同时还使用地图

问题描述

我正在使用 csvhelper 尝试将包含嵌套字典的项目集合导出到 csv。

我还需要根据当前的文化更改标题名称。我已经设法通过下面显示的映射进行标题翻译,因此我需要能够保留此功能,同时还支持嵌套字典。

CultureInfo currentCulture = localeCode == null ? CultureInfo.CurrentCulture : new CultureInfo(localeCode);
var rm = new ResourceManager("fileName", Assembly.GetExecutingAssembly());

Map(m => m.Id).Name(rm.GetString("Id", currentCulture));
Map(m => m.Name).Name(rm.GetString("Name", currentCulture));

我曾尝试使用 ExpandoObjects 并且似乎确实有效,但是我想知道是否有更优雅的解决方案。

// distinct list of all keys in the dictionary
var customAttributeNames = collection.SelectMany(c => c.CustomAttributes.Keys).Distinct().ToList();
var records = new List<dynamic>();
    foreach (var item in collection)
    {
        IDictionary<string, object> record = new ExpandoObject();
        record["Id"] = item.Id;
        record["Name"] = item.Name;

        // This is the nested dictionary 
        foreach (var name in customAttributeNames)
        {
            item.CustomAttributes.TryGetValue(name, out var value);
            record.Add(name, value);
        }
        records.Add(record);
    }

    using (var writer = new StringWriter())
    using (var csv = new CsvWriter(writer))
    {
        csv.WriteRecords(records);
    }

标签: c#dictionarynestedcsvhelper

解决方案


为什么不尝试为该属性使用 JsonFormatter。这个简单的例子很好用

public class MyClass
{
    public int Number { get; set; }
    public Dictionary<string, string> Value { get; set; }
}

public class JsonConverter : ITypeConverter
{
    public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
    {
        return JsonConvert.SerializeObject(value);
    }

    public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        return JsonConvert.DeserializeObject<Dictionary<string, string>>(text);
    }
}

public class MyClassMap : ClassMap<MyClass>
{
    public MyClassMap()
    {
        var i = 0;
        Map(m => m.Number).Index(i++);
        Map(m => m.Value).Index(i++).TypeConverter<JsonConverter>();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var list = Enumerable.Range(0, 5).Select(x => new MyClass()
        {
            Number = x,
            Value = new Dictionary<string, string>()
            {
                {x.ToString(), x + 1.ToString()}
            }
        });
        using (var writer = new StringWriter())
        using (var csv = new CsvWriter(writer)
        {
            Configuration = { HasHeaderRecord = true },

        })
        {
            csv.Configuration.RegisterClassMap<MyClassMap>();
            csv.WriteRecords(list);
            writer.Flush();
            Console.WriteLine(writer.ToString());
        }

    }
}

推荐阅读