【问题标题】:Transform CSV input (1 field) to destination class (2 fields)将 CSV 输入(1 个字段)转换为目标类(2 个字段)
【发布时间】:2020-03-29 17:47:39
【问题描述】:

我正在编写我的 ClassMap,它适用于我的第一个基本字段(包括列名与类成员不匹配的字段)。 但我有 2 个领域需要特定的工作

1) 我将颜色存储为字符串。我需要一些将输入转换为 2 个值并将每个值存储在特定成员中的代码。

2) 我有一个与 CSV 项目 ID 匹配的 ID(即父亲或母亲 ID)。但我需要将其转换为我数据库中的 ID(所以我必须编写一些代码来将 CSV_ID 与 DB_ID 匹配)。

是否可以使用 CSVHelper 添加此自定义逻辑? 感谢帮助。 文森特

【问题讨论】:

标签: c# csvhelper


【解决方案1】:

看起来,CSVHelper 在类映射期间也支持相同的类型转换器注入。

https://joshclose.github.io/CsvHelper/examples/configuration/class-maps/type-conversion

通过将这一点与对备用名称映射的支持相结合,

https://joshclose.github.io/CsvHelper/examples/configuration/class-maps/mapping-by-alternate-names

有一个这样的 csv 文件:

Id,Name,Color
1,OGUZ OZGUL,#f0f0f0
2,VINCENT,#80A0C0
3,OZGUL OGUZ,#00A000

有可能实现如下需求:

using System;
using System.Globalization;
using System.IO;
using CsvHelper;
using CsvHelper.Configuration;
using CsvHelper.TypeConversion;
using System.Linq;

namespace console
{
    public class Program
    {
        public class Foo
        {
            // Represents the database Id
            public int Id { get; set; }
            public string Name { get; set; }
            // Represents a three character color code, like #FFF
            public string Color3 { get; set; }
            // Represents a six character color code like #FFFFFF
            public string Color6 { get; set; }
        }

        // OK, we are not converting between types here, but who cares?
        // CSVHelper certainly doesn't.
        public class IdConverter : DefaultTypeConverter
        {
            public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
            {
                string csvId = text;
                int databaseId = Convert.ToInt32(text) + 10000;
                return databaseId;
            }

            public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
            {
                return ((int)value - 10000).ToString();
            }
        }

        // Again, we are changing the value as we wish, not the type.
        public class Color3Converter : DefaultTypeConverter
        {
            public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
            {
                // format: #ffffff
                return "#" + text[1] + text[3] + text[5];
            }

            public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
            {
                // format: #fff
                return "#" + ((string)value)[1] + "0" + ((string)value)[2] + "0" + ((string)value)[3] + "0";
            }
        }

        // By combining a type converter and alternative name
        // we achieve one CSV field value to be mapped to two properties
        // of our class Foo
        public sealed class FooMap : ClassMap<Foo>
        {
            public FooMap()
            {
                Map(m => m.Id).TypeConverter<IdConverter>();
                Map(m => m.Name);
                Map(m => m.Color3).TypeConverter<Color3Converter>().Name("Color");
                Map(m => m.Color6).Name("Color");
            }
        }

        static void Main(string[] args)
        {
            using (var reader = new StreamReader("data.csv"))
            {
                using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
                {
                    csv.Configuration.RegisterClassMap<FooMap>();
                    Foo[] records = csv.GetRecords<Foo>().ToArray();
                    foreach(Foo record in records)
                    {
                        Console.WriteLine
                        (
                            "Foo, Id: {0}, Name: {1}, Color3: {2}, Color6: {3}",
                             record.Id,
                             record.Name,
                             record.Color3,
                             record.Color6  
                        );
                }    
                }
            }
        }
    }
}

程序的输出是:

Foo, Id: 10001, Name: OGUZ OZGUL, Color3: #fff, Color6: #f0f0f0
Foo, Id: 10002, Name: VINCENT, Color3: #8AC, Color6: #80A0C0
Foo, Id: 10003, Name: OZGUL OGUZ, Color3: #0A0, Color6: #00A000

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2015-01-26
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多