dotnet/efcore · error · InvalidOperationException
The replacement entity type: {entityType} does not have same
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
FromSqlQueryRootExpression.UpdateEntityType throws InvalidOperationException when the replacement IEntityType differs from the query root's entity type in either Name or CLR type. The query root is bound to a specific entity type (its SQL and argument are tied to it), so swapping to a different entity would be invalid; EF requires an exact name+CLR match.
Source
Thrown at src/EFCore.Relational/Query/Internal/FromSqlQueryRootExpression.cs:81
/// <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 Expression DetachQueryProvider()
=> new FromSqlQueryRootExpression(EntityType, Sql, Argument);
/// <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 FromSqlQueryRootExpression(entityType, Sql, Argument);
/// <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 Expression VisitChildren(ExpressionVisitor visitor)
{
var argument = visitor.Visit(Argument);
return argument != Argument
? new FromSqlQueryRootExpression(EntityType, Sql, argument)
: this;
}
/// <summary>View on GitHub (pinned to dbf9771522)
Solutions
- Pass an IEntityType with the same Name and the same ClrType as the original query root's EntityType.
- If you need a different entity, construct a new FromSqlQueryRootExpression for that entity rather than updating an existing one.
- Avoid mutating query roots in custom visitors; rebuild the tree from the correct entity type.
Example fix
// before var newRoot = fromSqlRoot.UpdateEntityType(otherEntityType); // name/CLR differs -> throws // after - use a matching entity type, or build a new root var matching = model.FindEntityType(typeof(Order))!; // same Name + ClrType var newRoot = fromSqlRoot.UpdateEntityType(matching); // or: var fresh = new FromSqlQueryRootExpression(queryProvider, otherEntityType, sql, arg);
Defensive patterns
Strategy: validation
Validate before calling
static IEntityType ValidateSameEntity(IEntityType original, IEntityType replacement)
{
if (replacement.Name != original.Name || replacement.ClrType != original.ClrType)
throw new InvalidOperationException($"Replacement entity {replacement.DisplayName()} differs from {original.DisplayName()}.");
return replacement;
} Type guard
static bool IsSameEntityType(IEntityType a, IEntityType b) => a.Name == b.Name && a.ClrType == b.ClrType;
Try / catch
try { return root.UpdateEntityType(replacement); }
catch (InvalidOperationException ex) when (ex.Message.Contains("does not have same name and CLR type"))
{ /* construct a fresh query root for the new entity instead */ throw; } Prevention
- Only pass an entity type with identical Name and ClrType to UpdateEntityType.
- Build a new FromSqlQueryRootExpression when you need a different entity.
- Do not rewrite query roots mid-translation in custom visitors.
When it happens
Trigger: Calling UpdateEntityType with an IEntityType whose Name (model-qualified name) or ClrType differs from the original; a query-translation extension attempting to retarget a FromSql query root to a different entity; model remapping that changes the entity type mid-translation.
Common situations: Custom query translators/visitors that try to swap entity types; TPH/TPT inheritance remapping gone wrong; using a replacement entity type built for a different CLR type; EF extension libraries mismatching entity types during tree rewriting.
Related errors
- Calling '{visitMethodName}' is not allowed. Visit the expres
- 'VisitChildren' must be overridden in the class deriving fro
- 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
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/3bfe0fec0481b231.
Report an issue: GitHub.