dotnet/efcore · error · InvalidOperationException
The mapping strategy '{mappingStrategy}' specified on '{enti
Error message
The mapping strategy '{mappingStrategy}' specified on '{entityType}' is not supported. What it means
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.
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) == nullView on GitHub (pinned to dbf9771522)
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.
Example fix
// before modelBuilder.Entity<Base>().Metadata["Relational:MappingStrategy"] = "TPCC"; // typo // after modelBuilder.Entity<Base>().UseTpcMappingStrategy();
Defensive patterns
Strategy: validation
Validate before calling
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal; // RelationalAnnotationNames is public via the RelationalExtensions
bool StrategyIsValid(IModel model)
{
var valid = new[] { "TPH", "TPC", "TPT" };
foreach (var et in model.GetEntityTypes())
{
var s = et.GetMappingStrategy();
if (s is not null && !valid.Contains(s)) return false;
}
return true;
} Try / catch
try { _ = context.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("mapping strategy", StringComparison.Ordinal) && ex.Message.Contains("not supported", StringComparison.Ordinal))
{
throw new InvalidOperationException("Unknown mapping strategy. Use UseTphMappingStrategy()/UseTptMappingStrategy()/UseTpcMappingStrategy().", ex);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The derived entity type '{entityType}' was configured with t
- The mapping strategy '{mappingStrategy}' specified on '{enti
- The mapping strategy '{mappingStrategy}' used for '{entityTy
- The specified discriminator value '{value}' for '{entityType
- The short name for '{entityType1}' is '{discriminatorValue}'
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/028c0fdc5338b36c.
Report an issue: GitHub.