dotnet/efcore · error · InvalidOperationException

The replacement entity type

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 when the replacement entity type's CLR type or full name differs from the entity type the query root was created for. UpdateEntityType is meant for replacing an entity type with an equivalent one (e.g., a different IEntityType instance for the same entity), not for switching to a genuinely different entity.

Solutions

  1. Verify your table-valued function mapping and entity type configuration are consistent — the TVF should return rows for exactly one entity type.
  2. If using inheritance + TVF, ensure the base and derived types share the same CLR type name as expected by the function mapping.
  3. Check for duplicate entity type registrations with different CLR types that could collide.
  4. File an issue at https://github.com/dotnet/efcore with the model configuration and TVF setup if this appears to be an internal bug.

Example fix

// before — TVF mapped to a type that gets replaced with a different CLR type during query
modelBuilder.HasDbFunction(typeof(MyContext).GetMethod(nameof(GetOrders))!)
    .HasName("dbo.GetOrders");
// inheritance causes UpdateEntityType to see a mismatched ClrType

// after — ensure TVF entity type is consistent with inheritance
modelBuilder.Entity<Order>().ToTable("Orders");
modelBuilder.HasDbFunction(typeof(MyContext).GetMethod(nameof(GetOrders))!)
    .HasName("dbo.GetOrders");
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    var result = await context.Set<Order>().FromSqlInterpolated($"SELECT * FROM dbo.GetOrders()").ToListAsync();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("does not have same name and CLR type"))
{
    logger.LogError(ex, "TVF query root entity type mismatch — check model configuration");
    // Simplify: avoid inheritance overrides on TVF-mapped entities
    throw;
}

Prevention

When it happens

Trigger: Internal EF Core pipeline calls UpdateEntityType during query processing (e.g., for TPT/TPC inheritance mapping or entity type replacement) and passes an IEntityType whose ClrType or Name doesn't match. This is typically an internal invariant violation, not a user API call.

Common situations: Using table-valued functions (HasDbFunction with IsBuiltIn or TVF mapping) combined with inheritance hierarchies (TPT/TPC) where entity type replacement logic encounters a mismatch. An EF Core internal bug in the query pipeline's entity type rewriting pass. Rare: a custom IEntityTypeSource or model configuration that produces conflicting entity type definitions.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/4f62b5ac49e90351. Report an issue: GitHub.

Appendix: 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 to

View on GitHub (pinned to 3a2006ef56)