dotnet/efcore · error · InvalidOperationException
An error occurred while reading a database value. The expect
Error message
An error occurred while reading a database value. The expected type was '{expectedType}' but the actual value was of type '{actualType}'. What it means
Materialization type mismatch: ThrowReadValueException reports 'expected type was X but the actual value was of type Y' when the underlying GetFieldValue throws InvalidCastException because the database value's runtime type cannot be coerced into the shaper's expected CLR type. The expected and actual type names are included.
Source
Thrown at src/EFCore.Relational/Query/Internal/BufferedDataReader.cs:1934
message = exception is NullReferenceException
|| Equals(value, DBNull.Value)
? RelationalStrings.ErrorMaterializingPropertyNullReference(entityType, propertyName, expectedType)
: exception is InvalidCastException
? CoreStrings.ErrorMaterializingPropertyInvalidCast(entityType, propertyName, expectedType, actualType)
: RelationalStrings.ErrorMaterializingProperty(entityType, propertyName);
}
else
{
message = exception is NullReferenceException
|| Equals(value, DBNull.Value)
? RelationalStrings.ErrorMaterializingValueNullReference(expectedType)
: exception is InvalidCastException
? RelationalStrings.ErrorMaterializingValueInvalidCast(expectedType, actualType)
: RelationalStrings.ErrorMaterializingValue;
}
throw new InvalidOperationException(message, exception);
}
}
}
View on GitHub (pinned to dbf9771522)
Solutions
- Add a HasConversion on the property to convert between the DB type and the CLR type (e.g. enum <-> string).
- Change the CLR property type to match what the provider returns (e.g. long instead of int).
- Fix the stored data / SQL so the column's type matches the model.
- For SQLite dynamic typing, ensure stored values are of the expected type or use conversions.
Example fix
// before - DB stores enum as string, property is enum (no conversion)
public OrderStatus Status { get; set; }
// after - explicit conversion
modelBuilder.Entity<Order>()
.Property(o => o.Status)
.HasConversion<string>(); Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in dbContext.Model.GetEntityTypes())
foreach (var p in et.GetProperties())
if (p.ClrType.IsEnum && p.GetValueConverter() == null && p.GetColumnType() is string s && s.Contains("char"))
Console.WriteLine($"{et}.{p.Name}: enum likely stored as string but has no conversion; add .HasConversion<string>()."); Try / catch
try { return ctx.Set<T>().ToList(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("expected type was") && ex.Message.Contains("actual value was of type"))
{ _logger.LogError(ex, "Type mismatch on materialization; add HasConversion or change CLR type."); throw; } Prevention
- Add HasConversion for enums and provider-specific numeric/string types.
- Align CLR numeric types with the provider's returned types (e.g. long vs int).
- For SQLite, normalize stored types to match the model.
When it happens
Trigger: A column returns a value of a type incompatible with the mapped property (e.g. DB returns string but property is int; provider returns long for an int property on some dialects); a value converter mismatch; enum stored as string but mapped as int without conversion.
Common situations: Enum stored as string in DB but property is the enum/int without HasConversion; JSON/JSONB returned as string but property is a typed object; provider returning a different numeric type (e.g. bigint for an int column); SQLite dynamic typing where a column holds an unexpected type.
Related errors
- The required column '{column}' was not present in the result
- The underlying reader doesn't have as many fields as expecte
- An error occurred while reading a database value. See the in
- An error occurred while reading a database value. The expect
- Got translated node of type '{Result?.GetType().Name ?? "<nu
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/5b0cf0582713b173.
Report an issue: GitHub.