Description
openedon Feb 8, 2021
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