dotnet/efcore · error · InvalidOperationException
QueryRootDifferentEntityType
QueryRootDifferentEntityType
Error message
The replacement entity type: {entityType} does not have same name and CLR type as entity type this query root represents. What it means
Thrown by TableValuedFunctionQueryRootExpression.UpdateEntityType (TableValuedFunctionQueryRootExpression.cs:78) when the replacement entity type differs from the query root's entity type in either CLR type or name. A table-valued-function query root is bound to a specific entity type; replacing it with an incompatible one would desync the TVF mapping from the shaper, so EF refuses.
Source
Thrown at src/EFCore.Relational/Query/Internal/TableValuedFunctionQueryRootExpression.cs:78
arguments.Add(newArgument);
changed |= argument != newArgument;
}
return changed
? new TableValuedFunctionQueryRootExpression(EntityType, Function, arguments)
: this;
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public override EntityQueryRootExpression UpdateEntityType(IEntityType entityType)
=> entityType.ClrType != EntityType.ClrType
|| entityType.Name != EntityType.Name
? throw new InvalidOperationException(CoreStrings.QueryRootDifferentEntityType(entityType.DisplayName()))
: new TableValuedFunctionQueryRootExpression(entityType, Function, Arguments);
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override void Print(ExpressionPrinter expressionPrinter)
{
expressionPrinter.Append(Function.Name);
expressionPrinter.Append("(");
expressionPrinter.VisitCollection(Arguments);
expressionPrinter.Append(")");
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject toView on GitHub (pinned to dbf9771522)
Solutions
- Ensure the entity type passed to UpdateEntityType has the same ClrType and Name as the original query root's EntityType.
- Recreate the query root for the new entity type instead of calling UpdateEntityType with a mismatched type.
- If rebinding to a derived type, build a new TableValuedFunctionQueryRootExpression for that type.
- Verify you are using entity types from the same IModel the query was compiled against.
Example fix
// before - rebinding a TVF query root to an incompatible entity type var newRoot = tvfQueryRoot.UpdateEntityType(otherEntityType); // ClrType/Name differ -> throws // after - ensure the replacement matches, or construct a fresh root for the target type var matchingType = model.FindEntityType(originalEntityType.Name)!; // same name + CLR type var newRoot = tvfQueryRoot.UpdateEntityType(matchingType); // or: var fresh = new TableValuedFunctionQueryRootExpression(targetType, function, args);
Defensive patterns
Strategy: validation
Validate before calling
// Before UpdateEntityType, ensure name + CLR type match.
static bool IsCompatible(IEntityType original, IEntityType replacement)
=> original.ClrType == replacement.ClrType && original.Name == replacement.Name;
// Usage: if (!IsCompatible(root.EntityType, newType)) { /* build a fresh root */ } Type guard
static bool EntityTypeMatches(IEntityType a, IEntityType b) => a.Name == b.Name && a.ClrType == b.ClrType;
Try / catch
try { var r = root.UpdateEntityType(newType); }
catch (InvalidOperationException ex) when (ex.Message.Contains("does not have same name and CLR type")) {
// Replacement entity type is incompatible; construct a new query root instead.
var fresh = new TableValuedFunctionQueryRootExpression(newType, function, args);
} Prevention
- Only pass entity types with matching name + CLR type to UpdateEntityType.
- Construct a fresh query root when rebinding to a different type.
- Use entity types from the same IModel the query was compiled against.
- Add a guard asserting name/CLR-type equality before rebinding.
When it happens
Trigger: Calling UpdateEntityType on a TableValuedFunctionQueryRootExpression with an IEntityType whose ClrType or Name differs from the original. Encountered by EF internals (e.g. model conformance / replacing query roots during precompilation) or by advanced code that manipulates query trees / implements a custom IQueryTranslationPreprocessor.
Common situations: Custom query-root rewriting that swaps entity types; using an entity type from a different model instance; TPT/TPC or entity-splitting scenarios where a TVF query root is rebound to a derived/different type; bugs in providers/extensions that call UpdateEntityType with mismatched types.
Related errors
- Cosmos-specific methods can only be used when the context is
- Unhandled expression '{expression}' of type '{expressionType
- The replacement entity type: {entityType} does not have same
- Metadata model returned should not be 'null'. Provider: {pro
- UnableToBindMemberToEntityProjection
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/bb62095bd2de6054.
Report an issue: GitHub.