tnk479
tnk479

Reputation: 794

Error, Must specify valid information for parsing in the string, when using EF Core Value Conversion

Based on the EF Core docs (https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions), I'm trying to use EF Core's new Value Conversion on an enumeration. I want to save the enumeration as a string in the SQL Database table.

Here's the entity and enumeration.

public enum InputSetType
{
    TypeA, TypeB
}

public class MonthlyInputSet
{
    public int Id { get; set; }
    public InputSetType Type { get; set; }
}

Here is where I configure the MonthlyInputSet Entity:

public class MonthlyInputSetConfiguration : IEntityTypeConfiguration<MonthlyInputSet>
{
    public void Configure(EntityTypeBuilder<MonthlyInputSet> builder)
    {
        builder.Property(mis => mis.Type).HasConversion(v => v.ToString(), v => (InputSetType)Enum.Parse(typeof(InputSetType), v));
    }
}

So, I try to run a basic query to get this data and it fails. The query is:

var saved = await _context.MonthlyInputSets.Include(mis => mis.InsertedBy)
                                                     .Include(mis => mis.UpdatedBy)
                                                     .Include(mis => mis.MonthlyInputs)
                                                         .ThenInclude(mi => mi.EmissionsUnit)
                                                     .FirstOrDefaultAsync(mis => mis.Id == id);

But, an error is thrown on the first line of this query that says, "ArgumentException: Must specify valid information for parsing in the string." So my guess is that I have not properly configured the conversion of the string in the table to the enum in C#.

Full raw stack trace:

enter image description here

I verified that the correct string value is being returned from the database. It is not null and it is not a blank string. The string value returned matches a member of the enum perfectly.

 public void Configure(EntityTypeBuilder<MonthlyInputSet> builder)
    {
        builder.Property(mis => mis.Type).HasConversion(
            convertToProviderExpression: v => v.ToString(), 
            convertFromProviderExpression: v => Troubleshooting(v)
        );
    }

    private InputSetType Troubleshooting(string v)
    {
        return (InputSetType)Enum.Parse(typeof(InputSetType), v);
    }

these two images show that the text in every row in the database type column is identical to the 2nd member of the enum that is mapped to this field.

enter image description here enter image description here

Upvotes: 5

Views: 12572

Answers (2)

Panagiotis Kanavos
Panagiotis Kanavos

Reputation: 131722

The only way I can reproduce this error is for v to be an empty string, ie "". Not a null.

This :

Enum.Parse(typeof(InputSetType),"xx")

Throws Requested value 'xx' was not found..

While this:

 Enum.Parse(typeof(InputSetType),"")

Throws :

Must specify valid information for parsing in the string. (Parameter 'value')

It seems some rows contain an empty string instead of null.

You'll have to decide what to do with those values - are they bad data? Or should the application handle them and replace them with some default value?

If you decide to use a default value you could use String.IsEmptyorString.IsNullOrWhitespace` to handle them, eg:

v=> String.NullOrWhitespace(v)?InputSetType.Unknown:Enum.Parse(typeof(InputSetType),v)

Upvotes: 5

StakAtak
StakAtak

Reputation: 127

Probably this exception is caused by invalid data in the database - data, that is not present in the enum, null, empty string or so on. This error is common in Enum.Parse() so I think it is related to this method.

Upvotes: 0

Related Questions