当使用ChoETL导入csv时,如何将字符串Map到自定义类型?

hwamh0ep  于 2023-07-31  发布在  其他
关注(0)|答案(3)|浏览(114)

我正在将销售订单的csv导入CsvSalesOrder对象。CsvSalesOrder有一个Address属性,它的属性属于名为CustomString的自定义类型。如何在导入字符串时将其转换为CustomString类型?我的CustomString类:

public struct CustomString
{
    public string Value { get; }

    public CustomString(string val)
    {
        if (string.IsNullOrWhiteSpace(val))
        {
            Value = null;
        }
        else
        {
            Value = val.ToUpper();
        }
    }

    public static implicit operator string(CustomString s) => s.Value;
    public static explicit operator CustomString(string s) => new CustomString(s);
    public override string ToString() => Value;
}

字符串
我的Map设置:

var config = new ChoCSVRecordConfiguration<T>()
        .WithFirstLineHeader()
        .Configure(c => c.ThrowAndStopOnMissingField = false)
        .Configure(c => c.IgnoreEmptyLine = true)
        .Configure(c => c.FileHeaderConfiguration.IgnoreColumnsWithEmptyHeader = true);

foreach (var header in headers)
{
    if (mapping.TryGetValue(header, out var propName))
        config.Map(propName, header);
}


我的导入代码:

using var reader = new ChoCSVReader<T>(stream, config)
        .WithMaxScanRows(2)
        .QuoteAllFields()
        .IgnoreFieldValueMode(ChoIgnoreFieldValueMode.Any);
return reader.AsTypedEnumerable<T>();


尝试导入时,“地址”字段均为空。我试着添加一个类型转换器,但它不起作用。

ChoCSVRecordFieldConfiguration customStringConfig = new ChoCSVRecordFieldConfiguration("Address1");
customStringConfig.AddConverter(TypeDescriptor.GetConverter(typeof(CustomString)));
config.CSVRecordFieldConfigurations.Add(customStringConfig);

zujrkrfu

zujrkrfu1#

添加您自己的TypeConverter

public class CustomStringTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string s) {
            return new CustomString(s);
        } else {
            return base.ConvertFrom(context, culture, value);
        }
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string) && value is CustomString customString) {
            return customString.Value;
        } else {
            return base.ConvertTo(context, culture, value, destinationType);
        }
    }
}

字符串
我不知道ChoETL,因此我不确定这是否解决了问题,或者是否存在其他配置问题。

vuv7lop3

vuv7lop32#

您不需要自定义值转换器,因为CustomString已经实现了隐式类型转换运算符。
这里是示例,如何做没有转换器
https://dotnetfiddle.net/uFrlCg
下面是一个使用转换器的示例
https://dotnetfiddle.net/ia5e50

lf5gs5x2

lf5gs5x23#

感谢@Cinchoo的输入,我更新了代码。以下是更新的部分:

using (var reader = new ChoCSVReader<T>(stream, config)
            .WithMaxScanRows(2)
            .QuoteAllFields()
            .IgnoreFieldValueMode(ChoIgnoreFieldValueMode.Any)
            )
        {
            return reader.AsTypedEnumerable<T>().ToList();
        }

字符串
我不得不添加.ToList()以在阅读器被处理之前获得列表。我还更新了using语法和ChoETL包的版本。

相关问题