dotnet/efcore · error · InvalidOperationException
Using '{methodName}' on DbSet of '{entityType}' is not suppo
Error message
Using '{methodName}' on DbSet of '{entityType}' is not supported since '{entityType}' is part of hierarchy and does not contain a discriminator property. What it means
GenerateFromSqlQueryRoot (RelationalQueryableExtensions.cs:192), used by FromSql/FromSqlRaw/FromSqlInterpolated, throws when the target entity type is part of an inheritance hierarchy (has a base type or derived types) but has no discriminator property. FromSql over DbSet needs a single concrete row-to-type mapping; without a discriminator EF cannot decide which hierarchy member each row represents, so it only supports TPH roots with a discriminator.
Source
Thrown at src/EFCore.Relational/Extensions/RelationalQueryableExtensions.cs:192
return queryableSource.Provider.CreateQuery<TEntity>(
GenerateFromSqlQueryRoot(
queryableSource,
sql.Format,
sql.GetArguments()));
}
private static FromSqlQueryRootExpression GenerateFromSqlQueryRoot(
IQueryable source,
string sql,
object?[] arguments,
[CallerMemberName] string memberName = null!)
{
var entityQueryRootExpression = (EntityQueryRootExpression)source.Expression;
var entityType = entityQueryRootExpression.EntityType;
return (entityType.BaseType != null || entityType.GetDirectlyDerivedTypes().Any())
&& entityType.FindDiscriminatorProperty() == null
? throw new InvalidOperationException(
RelationalStrings.MethodOnNonTphRootNotSupported(memberName, entityType.DisplayName()))
: new FromSqlQueryRootExpression(
entityQueryRootExpression.QueryProvider!,
entityType,
sql,
Expression.Constant(arguments));
}
#endregion
#region SplitQuery
/// <summary>
/// Returns a new query which is configured to load the collections in the query results in a single database query.
/// </summary>
/// <remarks>
/// <para>
/// This behavior generally guarantees result consistency in the face of concurrent updatesView on GitHub (pinned to dbf9771522)
Solutions
- Call FromSql on the hierarchy root DbSet and let EF route rows by discriminator (requires TPH with a configured discriminator).
- If using TPT/TPC, switch to a plain SQL projection (e.g. context.Set<DerivedEntity>().FromSqlRaw on a TVF/view is not supported either) - instead execute raw SQL via ADO.NET or use a keyless entity/SQL query mapping.
- Ensure the discriminator is configured: modelBuilder.Entity<Base>().HasDiscriminator(b => b.Type) and that the entity is the TPH root.
- If you must target a derived type only, map a separate keyless entity or a defining query backed by raw SQL.
Example fix
// before (TPT/TPC, derived type)
var managers = context.Set<Manager>().FromSqlRaw("SELECT * FROM Managers").ToList(); // throws
// after - query the root in a TPH hierarchy with discriminator
var managers = context.Employees
.FromSqlRaw("SELECT * FROM Employees WHERE Discriminator = 'Manager'")
.OfType<Manager>().ToList(); Defensive patterns
Strategy: validation
Validate before calling
IEntityType entityType = context.Model.FindEntityType(typeof(TEntity))!;
bool isHierarchyRoot = entityType.BaseType == null;
bool hasDiscriminator = entityType.FindDiscriminatorProperty() != null;
bool inHierarchy = entityType.BaseType != null || entityType.GetDerivedTypes().Any();
if (inHierarchy && !hasDiscriminator)
{
// FromSql on this DbSet will throw; query the root or avoid FromSql.
} Type guard
static bool SupportsFromSql<T>(IModel model) where T : class
{
var et = model.FindEntityType(typeof(T))!;
var inHierarchy = et.BaseType != null || et.GetDerivedTypes().Any();
return !inHierarchy || et.FindDiscriminatorProperty() != null;
} Prevention
- Call FromSql on the hierarchy root, not on derived DbSets.
- Use TPH with a configured discriminator when raw-SQL entry points are needed.
- Check the discriminator exists before composing raw SQL in shared code.
When it happens
Trigger: Calling context.Set<DerivedEntity>().FromSqlRaw(...) or FromSqlInterpolated on a DbSet whose entity is in a TPT/TPC hierarchy, or a TPH hierarchy where the discriminator was removed/misconfigured. Also triggers when calling FromSql on a derived type rather than the hierarchy root.
Common situations: TPT or TPC hierarchies (no shared discriminator); mapped a discriminator but later removed it; calling FromSql on a derived entity instead of the base; hierarchy recently refactored from TPH to TPT.
Related errors
- SelectExpressionNonTphWithCustomTable
- The mapping strategy '{mappingStrategy}' specified on '{enti
- The specified discriminator value '{value}' for '{entityType
- The short name for '{entityType1}' is '{discriminatorValue}'
- The derived entity type '{entityType}' was configured with t
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/c6c9a303812d6911.
Report an issue: GitHub.