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 replaces the entity type backing a FromSqlRaw/FromSqlInterpolated query root during query compilation. It requires the replacement type to have both the same Name and the same ClrType as the original; otherwise it throws InvalidOperationException. This guards the identity contract of a raw-SQL query root.
Source
Thrown at src/EFCore.Cosmos/Query/Internal/Expressions/FromSqlQueryRootExpression.cs:83
/// <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
- Issue FromSqlRaw against the DbSet of the exact entity type you intend to query and avoid OfType/casts that change entity identity.
- If you need a derived view, write the SQL against that entity's container and call FromSqlRaw on its DbSet.
- Project into a DTO via Select instead of changing the query root's entity type.
Example fix
// before
var orders = ctx.Set<BaseOrder>()
.FromSqlRaw("SELECT * FROM c")
.OfType<SpecialOrder>(); // throws if identity differs
// after
var orders = ctx.Set<SpecialOrder>()
.FromSqlRaw("SELECT * FROM c WHERE c.Discriminator = 'SpecialOrder'"); Defensive patterns
Strategy: validation
Validate before calling
// Ensure OfType/cast target shares Name + ClrType with the FromSql root.
var root = cosmosModel.FindEntityType(typeof(BaseOrder))!;
var target = cosmosModel.FindEntityType(typeof(T))!;
if (root.Name != target.Name || root.ClrType != target.ClrType)
throw new InvalidOperationException("OfType target must match FromSql root identity."); Type guard
static bool IsSameQueryRootIdentity(IEntityType a, IEntityType b)
=> a.Name == b.Name && a.ClrType == b.ClrType; Try / catch
try { var q = ctx.Set<BaseOrder>().FromSqlRaw(sql).ToList(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("does not have same name and CLR type"))
{ /* reissue FromSqlRaw on the correct DbSet */ } Prevention
- Always call FromSqlRaw on the DbSet of the entity your SQL returns.
- Avoid OfType<>() after FromSqlRaw unless the type is the same identity.
- Document raw-SQL roots in integration tests.
When it happens
Trigger: Combining FromSqlRaw/FromSqlInterpolated with operators (e.g. OfType<T>, casts, or projection rewrites) that cause the pipeline to swap the root's entity type for one whose CLR type or model Name differs.
Common situations: Calling OfType<DerivedType>() on a FromSqlRaw query where DerivedType is not the same identity as the root entity; mixing raw SQL roots with inheritance hierarchies; upgrading EF Core and hitting a changed rewrite path.
Related errors
- A FromSqlExpression has an invalid arguments expression type
- 'WithPartitionKey' can only be called on an entity query roo
- QueryRootDifferentEntityType
- The type '{givenType}' cannot be mapped as a dictionary beca
- The value '{value}' provided for argument '{argumentName}' m
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/098322df7a03c1bd.
Report an issue: GitHub.