dotnet/efcore · error · InvalidOperationException
The entity type '{entityType}' is mapped to a SQL query, but
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 (RelationalModelValidator.cs:332-339) throws when an entity type that has a base type (is derived) is mapped to a SQL query (ToSqlQuery/defining query) whose definition differs from its base type's, or when the derived type has no discriminator. EF requires the whole hierarchy to read from the same SQL query, so a derived type mapping to its own SQL query is rejected.
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 dbf9771522)
Solutions
- Define the SQL query only on the base/root entity type and let derived types share it (with a discriminator for TPH).
- Ensure the derived type either has no SQL query (inherits the base's) or the same SQL query string as the base.
- If each type needs distinct SQL, model them as separate entity types (no inheritance) or separate keyless entities.
Example fix
// before - derived type mapped to its own SQL
modelBuilder.Entity<Person>().ToSqlQuery("SELECT * FROM People");
modelBuilder.Entity<Employee>().ToSqlQuery("SELECT * FROM Employees"); // throws
// after - share the base SQL, discriminate by column
modelBuilder.Entity<Person>().ToSqlQuery("SELECT * FROM People");
modelBuilder.Entity<Person>().HasDiscriminator(p => p.Type);
// do not call ToSqlQuery on Employee; it inherits the base query Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in context.Model.GetEntityTypes())
{
if (et.GetSqlQuery() != null && et.BaseType != null)
{
var baseQuery = et.BaseType.GetSqlQuery();
if (et.FindDiscriminatorProperty() == null || et.GetSqlQuery() != baseQuery)
{
// will throw - map SQL query only on the base and share it.
}
}
} Prevention
- Map ToSqlQuery() only on the hierarchy root; derived types inherit it.
- Keep a discriminator when using SQL-query mapping in a hierarchy.
- For per-type SQL, model separate non-inherited keyless entities.
When it happens
Trigger: Calling ToSqlQuery(...) (or setting GetSqlQuery) on a derived entity type with a different SQL than the base, or removing the discriminator while mapping a derived type to SQL. Thrown at model validation.
Common situations: Inheritance hierarchies where each derived type tries to supply its own raw SQL; refactoring a keyless SQL-query mapping into a hierarchy; mixing TPT/TPC with SQL-query mappings.
Related errors
- 'HasDiscriminatorInJsonId' or 'HasRootDiscriminatorInJsonId'
- The element type of the result of '{dbFunction}' is mapped t
- The mapping strategy '{mappingStrategy}' specified on '{enti
- The specified discriminator value '{value}' for '{entityType
- The short name for '{entityType1}' is '{discriminatorValue}'
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/9aff8508d0c9c6c9.
Report an issue: GitHub.