dotnet/efcore · error · InvalidOperationException
The entity type ' ' is mapped to a SQL query, but is…
Error message
The entity type '{entityType}' is mapped to a SQL query, but is derived from '{baseEntityType}'. Derived entity types cannot be mapped to a different SQL query than the base entity type. What it means
ValidateSqlQuery throws InvalidMappedSqlQueryDerivedType when an entity type mapped to a SQL query (via ToSqlQuery/ToSqlQueryRaw) has a base type and either lacks a discriminator or its SQL query differs from its base's. Relational mapping requires that a derived entity in a hierarchy share the same defining SQL query as its base — only TPH-over-SQL-query is supported.
Solutions
- Define the SQL query only on the hierarchy root entity type and let derived types inherit it.
- If using TPH, ensure a discriminator is configured and only the root has ToSqlQuery.
- For per-type querying, use separate non-hierarchical entity types or FromSqlRaw on the root with discriminator filtering.
Example fix
// before — derived type has its own SQL query
modelBuilder.Entity<Base>().ToSqlQuery("SELECT * FROM base_view");
modelBuilder.Entity<Derived>().ToSqlQuery("SELECT * FROM derived_view"); // throws
// after — root owns the SQL query; derived types inherit
modelBuilder.Entity<Base>().ToSqlQuery("SELECT * FROM base_view");
modelBuilder.Entity<Derived>().HasBase<Base>(); // no ToSqlQuery here Defensive patterns
Strategy: validation
Validate before calling
if (entityType.BaseType != null && entityType.GetSqlQuery() is not null
&& (entityType.FindDiscriminatorProperty() == null
|| entityType.GetSqlQuery() != entityType.BaseType.GetSqlQuery()))
throw new InvalidOperationException("Derived entity cannot have a different SQL query than its base."); Type guard
static bool CanMapToSqlQuery(IEntityType e)
=> e.BaseType == null
|| (e.FindDiscriminatorProperty() is not null
&& e.GetSqlQuery() == e.BaseType?.GetSqlQuery()); Prevention
- Define ToSqlQuery only on the hierarchy root.
- When using TPH with SQL-query mapping, ensure a discriminator is configured.
- Avoid mapping derived types to separate views; query the root and filter instead.
When it happens
Trigger: Configuring ToSqlQuery("SELECT ...") on a derived entity type; or giving a derived entity a different SQL query string than its base while the hierarchy uses no discriminator. Either condition triggers the throw.
Common situations: Trying to use SQL-query mapping (e.g. database views or TVFs) per derived type in a TPT hierarchy; refactoring inheritance and forgetting to remove a ToSqlQuery on the derived type; scaffolding views in an inheritance hierarchy.
Related errors
- The element type of the result of
- The mapping strategy
- The short name for ' ' is ' ' which is the same for ' '…
- The specified discriminator value
- An Azure Cosmos DB container name is defined on entity type
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/9aff8508d0c9c6c9.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:336
/// Validates the SQL query mapping for an entity type.
/// </summary>
/// <param name="entityType">The entity type to validate.</param>
/// <param name="logger">The logger to use.</param>
protected virtual void ValidateSqlQuery(
IEntityType entityType,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
var sqlQuery = entityType.GetSqlQuery();
if (sqlQuery == null)
{
return;
}
if (entityType.BaseType != null
&& (entityType.FindDiscriminatorProperty() == null
|| sqlQuery != entityType.BaseType.GetSqlQuery()))
{
throw new InvalidOperationException(
RelationalStrings.InvalidMappedSqlQueryDerivedType(
entityType.DisplayName(), entityType.BaseType.DisplayName()));
}
}
/// <summary>
/// Validates a single sequence.
/// </summary>
/// <param name="sequence">The sequence to validate.</param>
/// <param name="logger">The logger to use.</param>
protected virtual void ValidateSequence(
ISequence sequence,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
}
/// <summary>
/// Validates a single database function.View on GitHub (pinned to 3a2006ef56)