How to use EnumConverter with CsvHelper

I am using CsvHelper to serialize the class to a csv file - until all is well here.

Now I am trying to find a way to convert the enum properties of a class to their int value in csv, so I could use CSV to bulk insert later.

I got to know the EnumConverter class in CsvHelper, but I can't figure out how to use it correctly as all my attempts fail.

Here is my display class code

 public sealed class MyMapping : CsvClassMap<TradingCalendarException>
    {
        public MyMapping()
        {
            EnumConverter enumConverter = new EnumConverter(typeof(CalendarExceptionEntityType));

            Map(m => m.ExceptionEntityType).Index(0).Name("EXCEPTION_ENTITY_TYPE").TypeConverter(enumConverter);
            Map(m => m.ExceptionEntityIdentifier).Index(1).Name("EXCEPTION_ENTITY_IDENTIFIER");
            Map(m => m.OptionType).Index(2).Name("OPTION_TYPE");
            Map(m => m.StartDatetime).Index(3).Name("EXCEPTION_START_DATETIME");
            Map(m => m.EndDatetime).Index(4).Name("EXCEPTION_END_DATETIME");
            Map(m => m.DataSourceType).Index(5).Name("DATA_SOURCE_TYPE");
            Map(m => m.Description).Index(6).Name("DESCRIPTION");
        }
    }

      

and the recording part

using (StreamWriter file = new StreamWriter(filePath, false, Encoding.UTF8))
        {
            CsvWriter writer = new CsvWriter(file);
            MyMapping mapping = new MyMapping();
            writer.Configuration.RegisterClassMap(mapping);

            writer.WriteRecords(calendarExceptionList);
        }

      

The rest of the display (indexing and naming) works , it's just an EnumConverter that doesn't make any changes.

I have not found any examples on the internet.

Thank!

+3


source to share


3 answers


This is the solution I made:

public class CalendarExceptionEnumConverter<T> : DefaultTypeConverter  where T : struct
    {
        public override string ConvertToString(TypeConverterOptions options, object value)
        {
            T result;
            if(Enum.TryParse<T>(value.ToString(),out result))
            {
                return (Convert.ToInt32(result)).ToString();
            }

            throw new InvalidCastException(String.Format("Invalid value to EnumConverter. Type: {0} Value: {1}",typeof(T),value));
        }
    }

      



and used it like the following:

Map(m => m.ExceptionEntityType).TypeConverter<CalendarExceptionEnumConverter<CalendarExceptionEntityType>>();

      

+3


source


I used Yarimi's solution but found that he cannot read the enum value back from the .csv (can write fine)

My solution is to make the class extend from EnumTypeConverter and not DefaultTypeConverter.

here is the complete code



    public class OurEnumConverter<T> : CsvHelper.TypeConversion.EnumConverter where T : struct
    {

        public OurEnumConverter(): base(typeof(T))
        { }

        public override string ConvertToString(CsvHelper.TypeConversion.TypeConverterOptions options, object value)
        {
            T result;
            if (Enum.TryParse<T>(value.ToString(), out result))
            {
                return (Convert.ToInt32(result)).ToString();
            }
            return base.ConvertToString(options, value);
            //throw new InvalidCastException(String.Format("Invalid value to EnumConverter. Type: {0} Value: {1}", typeof (T), value));
        }
        public override object ConvertFromString(TypeConverterOptions options, string text)
        {
            int parsedValue;
            //System.Diagnostics.Debug.WriteLine($"{typeof(T).Name} = {text}");
            if (Int32.TryParse(text, out parsedValue))
            {
                return (T)(object)parsedValue;
            }
            return base.ConvertFromString(options, text);
            //throw new InvalidCastException(String.Format("Invalid value to EnumConverter. Type: {0} Value: {1}", typeof(T), text));
        }

    }

      

and this is how it is used

public class TickTradeClassMap : CsvHelper.Configuration.CsvClassMap<TickData.TickTrade>
    {
        public TickTradeClassMap()
        {
            Map(m => m.price);
            Map(m => m.size);
            Map(m => m.exchange).TypeConverter<OurEnumConverter<ATExchangeEnum>>();
            Map(m => m.condition1).TypeConverter<OurEnumConverter<ATTradeConditionEnum>>();
        }
    }

      

+2


source


Add a property int

to your class TradingCalendarException

that casts back and forth to your custom enum CalendarExceptionEntityType

, for example:

public int ExceptionEntityTypeInt { 
    get { return (int)ExceptionEntityType; } 
    set { ExceptionEntityType = (CalendarExceptionEntityType)value; } 
}

      

Use Map(m => m.ExceptionEntityTypeInt).Index(0).Name("EXCEPTION_ENTITY_TYPE_INT")

enum instead of converterMap(m => m.ExceptionEntityType).Index(0).Name("EXCEPTION_ENTITY_TYPE").TypeConverter(new MyMapping())

0


source







All Articles