dotnet/efcore · error · InvalidOperationException

The entity type ' ' is not mapped, so by default the owned…

Error message

The entity type '{ownerType}' is not mapped, so by default the owned type '{navigation}.{ownedType}' will also be unmapped. If this is intended explicitly map the owned type to 'null', otherwise map it to a named '{storeObjectType}'.

What it means

Thrown inside ValidateNonTphMapping when an entity type is itself not mapped to a store object (StoreObjectIdentifier.Create returns null), but it has derived types that ARE mapped, and it owns an owned type that is also unmapped and not mapped to JSON. EF refuses to silently leave the owned type unmapped and asks you to state your intent explicitly.

Solutions

  1. Map the owner entity to a table/view so the owned type follows it.
  2. Explicitly map the owned type to null to declare it should be unmapped: modelBuilder.Entity<Owner>().OwnsOne(o => o.Address, a => a.ToJson(null)) / SetTableName(null) as appropriate.
  3. Map the owned type to its own named table/view explicitly.
  4. Remove the ownership if it is not needed.

Example fix

// before (owner unmapped, owned type inherits unmapped)
modelBuilder.Entity<OwnerBase>().HasNoKey();
modelBuilder.Entity<OwnerBase>().OwnsOne(o => o.Address); // throws 425

// after - explicitly map owned type to null
modelBuilder.Entity<OwnerBase>().OwnsOne(o => o.Address, a =>
{
    a.ToTable("Addresses"); // or a.ToJson(null) / explicit null mapping
});
Defensive patterns

Strategy: validation

Validate before calling

foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
    foreach (var sot in new[] { StoreObjectType.Table, StoreObjectType.View })
    {
        if (StoreObjectIdentifier.Create(entityType, sot) != null) continue;
        var hasMappedDerived = entityType.GetDerivedTypes().Any(d => StoreObjectIdentifier.Create(d, sot) != null);
        if (!hasMappedDerived) continue;
        var unmappedOwned = entityType.GetReferencingForeignKeys()
            .Where(fk => fk.IsOwnership)
            .Select(fk => fk.DeclaringEntityType)
            .FirstOrDefault(o => StoreObjectIdentifier.Create(o, sot) == null && !o.IsMappedToJson());
        if (unmappedOwned != null)
            throw new InvalidOperationException($"Owner {entityType.DisplayName()} is unmapped with unmapped owned {unmappedOwned.DisplayName()} for {sot}; map explicitly.");
    }
}

Prevention

When it happens

Trigger: A non-TPH hierarchy where an intermediate or base owner entity has no table/view mapping, has mapped derived types, and declares an owned type (HasOne/OwnsOne/OwnsMany) that is not explicitly mapped. The owner's unmapped state would cascade to the owned type.

Common situations: Abstract base types with owned collections; mixing TPT inheritance with owned types on an unmapped base; forgetting to map an owned type after splitting a hierarchy; refactor that left an owner without a table.

Related errors


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

Appendix: source

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

    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
                        && ((IConventionEntityType)owned).GetStoreObjectConfigurationSource(storeObjectType) == null
                        && !owned.IsMappedToJson());
                if (unmappedOwnedType != null
                    && entityType.GetDerivedTypes().Any(derived => StoreObjectIdentifier.Create(derived, storeObjectType) != null))
                {
                    throw new InvalidOperationException(
                        RelationalStrings.UnmappedNonTPHOwner(
                            entityType.DisplayName(),
                            unmappedOwnedType.FindOwnership()!.PrincipalToDependent?.Name,
                            unmappedOwnedType.DisplayName(),
                            storeObjectType));
                }

                continue;
            }

            if (derivedTypes.TryGetValue(storeObject.Value, out var otherType))
            {
                switch (storeObjectType)
                {
                    case StoreObjectType.Table:
                        throw new InvalidOperationException(
                            RelationalStrings.NonTphTableClash(
                                entityType.DisplayName(), otherType.DisplayName(), storeObject.Value.DisplayName()));

View on GitHub (pinned to 3a2006ef56)