{"record":{"id":"028c0fdc5338b36c","repo":"dotnet/efcore","slug":"the-mapping-strategy-mappingstrategy-specified-028c0f","errorCode":null,"errorMessage":"The mapping strategy '{mappingStrategy}' specified on '{entityType}' is not supported.","messagePattern":"The mapping strategy '(.+?)' specified on '(.+?)' is not supported\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":2201,"sourceCode":"            }\n        }\n    }\n\n    /// <summary>\n    ///     Validates that the given mapping strategy is supported\n    /// </summary>\n    /// <param name=\"entityType\">The entity type.</param>\n    /// <param name=\"mappingStrategy\">The mapping strategy.</param>\n    protected virtual void ValidateMappingStrategy(IEntityType entityType, string? mappingStrategy)\n    {\n        switch (mappingStrategy)\n        {\n            case RelationalAnnotationNames.TphMappingStrategy:\n            case RelationalAnnotationNames.TpcMappingStrategy:\n            case RelationalAnnotationNames.TptMappingStrategy:\n                break;\n            default:\n                throw new InvalidOperationException(\n                    RelationalStrings.InvalidMappingStrategy(\n                        mappingStrategy, entityType.DisplayName()));\n        }\n    }\n\n    private static void ValidateNonTphMapping(IEntityType rootEntityType, StoreObjectType storeObjectType)\n    {\n        var isTpc = rootEntityType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy;\n        var derivedTypes = new Dictionary<StoreObjectIdentifier, IEntityType>();\n        foreach (var entityType in rootEntityType.GetDerivedTypesInclusive())\n        {\n            var storeObject = StoreObjectIdentifier.Create(entityType, storeObjectType);\n            if (storeObject == null)\n            {\n                var unmappedOwnedType = entityType.GetReferencingForeignKeys()\n                    .Where(fk => fk.IsOwnership)\n                    .Select(fk => fk.DeclaringEntityType)\n                    .FirstOrDefault(owned => StoreObjectIdentifier.Create(owned, storeObjectType) == null","sourceCodeStart":2183,"sourceCodeEnd":2219,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L2183-L2219","documentation":"ValidateMappingStrategy inspects the MappingStrategy annotation placed on a root entity type and only accepts the three known values: TPH, TPC, or TPT (constants in RelationalAnnotationNames). Any other string (including typos, casing mistakes, or a value from a newer/older version) is rejected with an InvalidOperationException, because EF has no code path to honor it.","triggerScenarios":"Produced when entityType[RelationalAnnotationNames.MappingStrategy] is a non-null string other than \"TPH\", \"TPC\", or \"TPT\". Happens if you call .UseTpcMappingStrategy() on a custom fork, hand-set the annotation via .Metadata.FindAnnotation(...).Value = ..., pass a wrong constant, or build the model with code targeting a different EF Core version where a different strategy name was used.","commonSituations":"Mistyping the strategy name when setting the annotation directly; copy-pasting TPC/TPT code from a blog that uses a deprecated API; upgrading EF Core where strategy constants were renamed; provider plugins that inject a strategy EF does not recognize.","solutions":["Use the fluent API instead of raw annotations: modelBuilder.Entity<Base>().UseTpcMappingStrategy() / UseTptMappingStrategy() / UseTphMappingStrategy().","If setting the annotation by hand, use the RelationalAnnotationNames.TpcMappingStrategy / TptMappingStrategy / TphMappingStrategy constant rather than a string literal.","Verify the EF Core version across all projects is consistent (dotnet list package --include-transitive) so the strategy constant matches what the validator expects."],"exampleFix":"// before\nmodelBuilder.Entity<Base>().Metadata[\"Relational:MappingStrategy\"] = \"TPCC\"; // typo\n\n// after\nmodelBuilder.Entity<Base>().UseTpcMappingStrategy();","handlingStrategy":"validation","validationCode":"using Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Metadata.Internal; // RelationalAnnotationNames is public via the RelationalExtensions\n\nbool StrategyIsValid(IModel model)\n{\n    var valid = new[] { \"TPH\", \"TPC\", \"TPT\" };\n    foreach (var et in model.GetEntityTypes())\n    {\n        var s = et.GetMappingStrategy();\n        if (s is not null && !valid.Contains(s)) return false;\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try { _ = context.Model; }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"mapping strategy\", StringComparison.Ordinal) && ex.Message.Contains(\"not supported\", StringComparison.Ordinal))\n{\n    throw new InvalidOperationException(\"Unknown mapping strategy. Use UseTphMappingStrategy()/UseTptMappingStrategy()/UseTpcMappingStrategy().\", ex);\n}","preventionTips":["Prefer the fluent UseTphMappingStrategy()/UseTptMappingStrategy()/UseTpcMappingStrategy() over raw annotations.","Keep EF Core package versions aligned across the solution so strategy constants match the validator.","Never hand-type the strategy string; reference RelationalAnnotationNames constants."],"tags":["ef-core","model-validation","inheritance","mapping-strategy","relational"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}