{"record":{"id":"2a71fa361ab12441","repo":"dotnet/efcore","slug":"the-entity-type-ownertype-is-not-mapped-so-by","errorCode":null,"errorMessage":"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}'.","messagePattern":"The entity type '(.+?)' is not mapped, so by default the owned type '(.+?)\\.(.+?)' will also be unmapped\\. If this is intended explicitly map the owned type to 'null', otherwise map it to a named '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":2225,"sourceCode":"    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\n                        && ((IConventionEntityType)owned).GetStoreObjectConfigurationSource(storeObjectType) == null\n                        && !owned.IsMappedToJson());\n                if (unmappedOwnedType != null\n                    && entityType.GetDerivedTypes().Any(derived => StoreObjectIdentifier.Create(derived, storeObjectType) != null))\n                {\n                    throw new InvalidOperationException(\n                        RelationalStrings.UnmappedNonTPHOwner(\n                            entityType.DisplayName(),\n                            unmappedOwnedType.FindOwnership()!.PrincipalToDependent?.Name,\n                            unmappedOwnedType.DisplayName(),\n                            storeObjectType));\n                }\n\n                continue;\n            }\n\n            if (derivedTypes.TryGetValue(storeObject.Value, out var otherType))\n            {\n                switch (storeObjectType)\n                {\n                    case StoreObjectType.Table:\n                        throw new InvalidOperationException(\n                            RelationalStrings.NonTphTableClash(\n                                entityType.DisplayName(), otherType.DisplayName(), storeObject.Value.DisplayName()));","sourceCodeStart":2207,"sourceCodeEnd":2243,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L2207-L2243","documentation":"Raised by ValidateNonTphMapping when an entity type in a TPT/TPC hierarchy is itself unmapped to a given store object type, yet one of its owned navigations is also unmapped by default and at least one derived type in the hierarchy IS mapped to that store object type. EF cannot silently drop the owned entity from the hierarchy, so it asks you to be explicit: either confirm the owned type should be unmapped, or give it a concrete store object.","triggerScenarios":"Triggered when StoreObjectIdentifier.Create(entityType, storeObjectType) returns null for a non-TPH root, an ownership declared on it has no store object configuration source, the owned type is not JSON-mapped, and GetDerivedTypes().Any(derived mapped to that storeObjectType) is true. Typically appears when you map only some derived types to a table/view and leave the owner (and its owned navigation) unmapped.","commonSituations":"Mixing TPT table mapping with an owned entity on the base where the base has no ToTable; mapping derived types to views while leaving the base unmapped; partial hierarchy mappings introduced by scaffolded or hand-edited configurations.","solutions":["Explicitly map the owned navigation to null to confirm it is intentionally unmapped, or to a named store object: modelBuilder.Entity<Owner>().OwnsOne(o => o.Address, a => a.ToTable(\"Addresses\")).","Map the unmapped owner entity type to a store object of the same type (ToTable / ToView / ToFunction) so the hierarchy is fully represented.","Remove the derived-type mapping that left the hierarchy half-mapped if only the base should be persisted."],"exampleFix":"// before\nmodelBuilder.Entity<Owner>().OwnsOne(o => o.Address); // base Owner not mapped, derived types mapped\n\n// after\nmodelBuilder.Entity<Owner>().OwnsOne(o => o.Address, a => a.ToTable(\"Addresses\"));","handlingStrategy":"validation","validationCode":"bool NoUnmappedOwnedInNonTphHierarchy(DbContext context)\n{\n    foreach (var root in context.Model.GetEntityTypes()\n        .Where(e => e.BaseType == null && e.GetMappingStrategy() is \"TPT\" or \"TPC\"))\n    {\n        foreach (var et in root.GetDerivedTypesInclusive())\n        {\n            var owned = et.GetReferencingForeignKeys()\n                .Where(fk => fk.IsOwnership)\n                .Select(fk => fk.DeclaringEntityType)\n                .FirstOrDefault(o => StoreObjectIdentifier.Create(o, StoreObjectType.Table) == null\n                    && ((IConventionEntityType)o).GetStoreObjectConfigurationSource(StoreObjectType.Table) == null\n                    && !o.IsMappedToJson());\n            if (owned != null && et.GetDerivedTypes().Any(d => StoreObjectIdentifier.Create(d, StoreObjectType.Table) != null))\n                return false;\n        }\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try { _ = context.Model; }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"not mapped\", StringComparison.Ordinal) && ex.Message.Contains(\"owned type\", StringComparison.Ordinal))\n{\n    throw new InvalidOperationException(\"An owned navigation is unmapped in a non-TPH hierarchy. Explicitly map it with ToTable/ToView or to null.\", ex);\n}","preventionTips":["Always give owned navigations an explicit ToTable/ToView in TPT/TPC hierarchies.","Map the whole hierarchy (base + derived) consistently to the same store object type.","Add a model validation unit test that exercises context.Model after configuration."],"tags":["ef-core","model-validation","owned-types","tpt","tpc","relational"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}