Skip to content

Unknown database enum values are read as the default enum value when using .HasConversion<string> #24084

Closed

Description

When querying an entity with an enum field that has been mapped with .HasConversion<string>() (or manually with an EnumToStringConverter<>), Entity Framework reads unknown values in the database as the default value of the enum. This fallback behaviour is undesirable, as it can cause silent data corruption in memory.

Example

Enum in code

public enum State
{
	MyFirstState,
	MySecondState,
	MyThirdState
}

Data in database

Id	State
1	MyThirdState
2	MyThirdState
3	MyFourthState

Expected behaviour

Entity Framework throws an exception, either at model time or query time, as MyFourthState is not a recognized State value.

Actual behaviour

Entity Framework silently reads MyFourthState as MyFirstState, leading to data corruption in memory.

Entity Framework seems to assume that it is valid to translate the unknown string value to the default value of enums (i.e. whatever string represents 0 internally, in this case the first state).

Offending code

Seems to be the default fallback in this method in StringEnumConverter.cs, but I did not test:

        private static TEnum ConvertToEnum(string value)
            => Enum.TryParse<TEnum>(value, out var result)
                ? result
                : Enum.TryParse(value, true, out result)
                    ? result
                    : ulong.TryParse(value, out var ulongValue)
                        ? (TEnum)(object)ulongValue
                        : long.TryParse(value, out var longValue)
                            ? (TEnum)(object)longValue
                            : default;

Notes

I am unaware of whether the current behaviour is by design for some reason unbeknownst to me. Maybe there are other use cases that depend on the current behaviour.

Provider and version information

EF Core version: 5.0.2
Database provider: Microsoft.EntityFrameworkCore.Sqlite (i did not test with other providers, but this issue should not be provider dependent)
Target framework: netcoreapp3.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions