dotnet/efcore · error · InvalidOperationException

The mapping strategy

Error message

The mapping strategy '{mappingStrategy}' specified on '{entityType}' is not supported.

What it means

Thrown by ValidateMappingStrategy when the mapping strategy string set on an entity type is not one of the recognized values (TPH, TPC, TPT). The switch falls through to the default case, so any unknown/misspelled strategy annotation is rejected at validation time.

Solutions

  1. Use the fluent API: UseTphMappingStrategy(), UseTptMappingStrategy(), or UseTpcMappingStrategy().
  2. If setting the annotation directly, use RelationalAnnotationNames.TphMappingStrategy / TpcMappingStrategy / TptMappingStrategy constants, never literals.
  3. Check for trailing spaces or wrong casing in any custom convention that writes the strategy.

Example fix

// before
modelBuilder.Entity<Order>()
    .Metadata.SetAnnotation("Relational:MappingStrategy", "TablePerType"); // unknown -> throws 424

// after
modelBuilder.Entity<Order>().UseTptMappingStrategy();
Defensive patterns

Strategy: validation

Validate before calling

var allowed = new HashSet<string?>
{
    null,
    RelationalAnnotationNames.TphMappingStrategy,
    RelationalAnnotationNames.TptMappingStrategy,
    RelationalAnnotationNames.TpcMappingStrategy,
};
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
    var strategy = (string?)entityType[RelationalAnnotationNames.MappingStrategy];
    if (!allowed.Contains(strategy))
        throw new InvalidOperationException($"{entityType.DisplayName()} has unknown mapping strategy '{strategy}'.");
}

Prevention

When it happens

Trigger: Calling SetMappingStrategy with a typo or unsupported value (e.g. "TPTT", "TablePerHierarchy", "tpt" with wrong casing/format), or writing the RelationalAnnotationNames.MappingStrategy annotation directly with an invalid string.

Common situations: Hand-writing the annotation string instead of using UseTptMappingStrategy()/UseTpcMappingStrategy()/UseTphMappingStrategy(); custom conventions that set the annotation; casing/whitespace mistakes; stale code referencing a renamed strategy constant.

Related errors


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

Appendix: source

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

            }
        }
    }

    /// <summary>
    ///     Validates that the given mapping strategy is supported
    /// </summary>
    /// <param name="entityType">The entity type.</param>
    /// <param name="mappingStrategy">The mapping strategy.</param>
    protected virtual void ValidateMappingStrategy(IEntityType entityType, string? mappingStrategy)
    {
        switch (mappingStrategy)
        {
            case RelationalAnnotationNames.TphMappingStrategy:
            case RelationalAnnotationNames.TpcMappingStrategy:
            case RelationalAnnotationNames.TptMappingStrategy:
                break;
            default:
                throw new InvalidOperationException(
                    RelationalStrings.InvalidMappingStrategy(
                        mappingStrategy, entityType.DisplayName()));
        }
    }

    private static void ValidateNonTphMapping(IEntityType rootEntityType, StoreObjectType storeObjectType)
    {
        var isTpc = rootEntityType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy;
        var derivedTypes = new Dictionary<StoreObjectIdentifier, IEntityType>();
        foreach (var entityType in rootEntityType.GetDerivedTypesInclusive())
        {
            var storeObject = StoreObjectIdentifier.Create(entityType, storeObjectType);
            if (storeObject == null)
            {
                var unmappedOwnedType = entityType.GetReferencingForeignKeys()
                    .Where(fk => fk.IsOwnership)
                    .Select(fk => fk.DeclaringEntityType)
                    .FirstOrDefault(owned => StoreObjectIdentifier.Create(owned, storeObjectType) == null

View on GitHub (pinned to 3a2006ef56)