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
- Move the .ToFunction(name) call from the derived entity to the root entity configuration.
- Ensure the DbFunction returns IQueryable<RootType> and map only the root with ToFunction.
- 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
- Only call .ToFunction on the root entity of a hierarchy.
- In IEntityTypeConfiguration<T>, check T is the root before applying ToFunction.
- Review TPT/Tpc migrations to ensure derived configs don't carry ToFunction.
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
- The DbFunction ' ' returns ' ', but ' ' is not a mapped…
- The element type of the result of
- The entity type ' ' is mapped to the 'DbFunction' named ' '…
- The entity type ' ' is mapped to the 'DbFunction' named ' '…
- The entity type ' ' is mapped to the DbFunction named ' '…
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)