dotnet/efcore · error · InvalidOperationException

The entity type '{entityType}' cannot have a defining query

Error message

The entity type '{entityType}' cannot have a defining query because it is derived from '{baseType}'. Only base entity types can have a defining query.

What it means

Thrown by the InMemory model validator when a derived entity type (one with a BaseType) has an InMemory defining query configured. EF Core restricts defining queries to base entity types because derived types inherit the query from their parent; configuring one on a derived type is ambiguous and invalid.

Source

Thrown at src/EFCore.InMemory/Infrastructure/Internal/InMemoryModelValidator.cs:53

        ValidateDefiningQuery(model, logger);
    }

    /// <summary>
    ///     Validates the configuration of defining queries in the model.
    /// </summary>
    /// <param name="model">The model to validate.</param>
    /// <param name="logger">The logger to use.</param>
    protected virtual void ValidateDefiningQuery(
        IModel model,
        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
    {
        foreach (var entityType in model.GetEntityTypes())
        {
            if (entityType.GetInMemoryQuery() != null)
            {
                if (entityType.BaseType != null)
                {
                    throw new InvalidOperationException(
                        CoreStrings.DerivedTypeDefiningQuery(entityType.DisplayName(), entityType.BaseType.DisplayName()));
                }
            }
        }
    }
}

View on GitHub (pinned to 3a2006ef56)

Solutions

  1. Move the ToInMemoryQuery / HasDefiningQuery call to the root (base) entity type of the hierarchy.
  2. If only the derived set should be filtered, filter the source query inside the root entity's defining query using OfType<Derived>.
  3. Remove the defining query from the derived type and use a discriminator-aware query filter instead.

Example fix

// before - on derived type
modelBuilder.Entity<SpecialOrder>().ToInMemoryQuery(...);
// after - on root type
modelBuilder.Entity<Order>().ToInMemoryQuery(orders.Where(o => o is SpecialOrder).Cast<SpecialOrder>());
Defensive patterns

Strategy: validation

Validate before calling

foreach (var et in modelBuilder.Model.GetEntityTypes())
    if (et.BaseType is not null && et.GetInMemoryQuery() is not null)
        throw new InvalidOperationException($"Derived type {et.DisplayName()} cannot have a defining query");

Prevention

When it happens

Trigger: ValidateDefiningQuery iterates model.GetEntityTypes(); an entity with GetInMemoryQuery() != null also has entityType.BaseType != null at validation time.

Common situations: TPH/TPT hierarchies where the developer calls ToInMemoryQuery on a derived entity instead of the root. Migrating from HasQueryFilter to ToInMemoryQuery and applying it to the wrong end of a hierarchy.

Related errors


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