dotnet/efcore · error · InvalidOperationException

The entity type ' ' is mapped to the 'DbFunction' named '…

Error message

The entity type '{entityType}' is mapped to the 'DbFunction' named '{functionName}', but is derived from '{baseEntityType}'. Derived entity types cannot be mapped to a function.

What it means

Thrown in ValidateDbFunctionMapping when an entity type that has a function mapping also has a BaseType — i.e., it is a derived type in an inheritance hierarchy. The check at RelationalModelValidator.cs:437-442 fires after the function is found: only root entity types can be mapped to a DbFunction/TVF. Derived types inherit the root's mapping.

Solutions

  1. Move the .ToFunction(name) call from the derived entity to the root entity configuration.
  2. Ensure the DbFunction returns IQueryable<RootType> and map only the root with ToFunction.
  3. If you genuinely need per-derived-type rowsets, model separate keyless DTO entities outside the hierarchy.

Example fix

// before
modelBuilder.Entity<Animal>().ToTable("Animals");
modelBuilder.Entity<Dog>().ToFunction("dbo.Dogs"); // Dog derives from Animal

// after
public IQueryable<Animal> AnimalsTvf()
    => FromExpression(() => AnimalsTvf());
modelBuilder.HasDbFunction(() => AnimalsTvf());
modelBuilder.Entity<Animal>().ToFunction("AnimalsTvf"); // root only
Defensive patterns

Strategy: validation

Validate before calling

foreach (var et in modelBuilder.Model.GetEntityTypes())
{
    if (et.GetFunctionName() is null) continue;
    if (et.BaseType is not null)
        throw new InvalidOperationException($"Derived entity '{et.Name}' cannot be mapped to a function; map the root '{et.BaseType.Name}' instead.");
}

Try / catch

try { _ = ctx.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("Derived entity types cannot be mapped to a function"))
{
    logger.LogError("Move .ToFunction to the hierarchy root. {Msg}", ex.Message);
    throw;
}

Prevention

When it happens

Trigger: Configuring .ToFunction(name) on a derived entity type configuration (modelBuilder.Entity<Derived>().ToFunction(...)) while the base type is also configured. Or owning an inheritance hierarchy where each derived type tries to map to its own TVF.

Common situations: Misunderstanding that TVF mapping must live on the hierarchy root; refactoring a single-type model into a hierarchy and forgetting to move the ToFunction up to the base; using per-type TPT configuration and accidentally applying ToFunction to derived configs.

Related errors


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

Appendix: source

Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:439

        IEntityType entityType,
        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
    {
        var mappedFunctionName = entityType.GetFunctionName();
        if (mappedFunctionName == null)
        {
            return;
        }

        var mappedFunction = entityType.Model.FindDbFunction(mappedFunctionName);
        if (mappedFunction == null)
        {
            throw new InvalidOperationException(
                RelationalStrings.MappedFunctionNotFound(entityType.DisplayName(), mappedFunctionName));
        }

        if (entityType.BaseType != null)
        {
            throw new InvalidOperationException(
                RelationalStrings.InvalidMappedFunctionDerivedType(
                    entityType.DisplayName(), mappedFunctionName, entityType.BaseType.DisplayName()));
        }

        if (mappedFunction.IsScalar
            || mappedFunction.ReturnType.GetGenericArguments()[0] != entityType.ClrType)
        {
            throw new InvalidOperationException(
                RelationalStrings.InvalidMappedFunctionUnmatchedReturn(
                    entityType.DisplayName(),
                    mappedFunctionName,
                    mappedFunction.ReturnType.ShortDisplayName(),
                    entityType.ClrType.ShortDisplayName()));
        }

        if (mappedFunction.Parameters.Count > 0)
        {
            var parameters = "{"

View on GitHub (pinned to 3a2006ef56)