{"record":{"id":"9dfaeea02cf7421c","repo":"dotnet/efcore","slug":"the-entity-type-dependenttype-is-mapped-to-s","errorCode":null,"errorMessage":"The entity type '{dependentType}' is mapped to '{storeObject}'. However the principal entity type '{principalEntityType}' is also mapped to '{storeObject}' and it's using the TPC mapping strategy. Entity types in a TPC hierarchy can use table-sharing only if they have no derived types.","messagePattern":"The entity type '(.+?)' is mapped to '(.+?)'\\. However the principal entity type '(.+?)' is also mapped to '(.+?)' and it's using the TPC mapping strategy\\. Entity types in a TPC hierarchy can use table-sharing only if they have no derived types\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":2264,"sourceCode":"                            RelationalStrings.NonTphViewClash(\n                                entityType.DisplayName(), otherType.DisplayName(), storeObject.Value.DisplayName()));\n                    case StoreObjectType.InsertStoredProcedure:\n                    case StoreObjectType.DeleteStoredProcedure:\n                    case StoreObjectType.UpdateStoredProcedure:\n                        throw new InvalidOperationException(\n                            RelationalStrings.NonTphStoredProcedureClash(\n                                entityType.DisplayName(), otherType.DisplayName(), storeObject.Value.DisplayName()));\n                }\n            }\n\n            if (isTpc)\n            {\n                var rowInternalFk = entityType.FindDeclaredReferencingRowInternalForeignKeys(storeObject.Value)\n                    .FirstOrDefault();\n                if (rowInternalFk != null\n                    && entityType.GetDirectlyDerivedTypes().Any())\n                {\n                    throw new InvalidOperationException(\n                        RelationalStrings.TpcTableSharing(\n                            rowInternalFk.DeclaringEntityType.DisplayName(),\n                            storeObject.Value.DisplayName(),\n                            rowInternalFk.PrincipalEntityType.DisplayName()));\n                }\n            }\n\n            derivedTypes[storeObject.Value] = entityType;\n        }\n\n        var rootStoreObject = StoreObjectIdentifier.Create(rootEntityType, storeObjectType);\n        if (rootStoreObject == null)\n        {\n            return;\n        }\n\n        if (rootEntityType.FindRowInternalForeignKeys(rootStoreObject.Value).Any()\n            && derivedTypes.Count > 1","sourceCodeStart":2246,"sourceCodeEnd":2282,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L2246-L2282","documentation":"In ValidateNonTphMapping, when the hierarchy is TPC, EF allows a dependent entity to share a table with its principal via a row-internal foreign key ONLY if the dependent has no derived types of its own. If a dependent that table-shares also has directly derived types, EF cannot keep the TPC 'one table per concrete type' guarantee and throws.","triggerScenarios":"A dependent entity (typically an owned/inline type via row-internal FK) shares a table with its principal AND GetDirectlyDerivedTypes().Any() is true on it, while the root has TPC mapping strategy. Triggered when you mix table/owner sharing with TPC and then add an inheritance chain on the shared dependent.","commonSituations":"Adding a base+derived relationship to an owned type that was previously table-shared in a TPC hierarchy; converting an owned type to a hierarchy while keeping its ToTable equal to the principal's.","solutions":["Move the dependent to its own table so it no longer shares with the principal: modelBuilder.Entity<Dependent>().ToTable(\"Dependents\").","Remove inheritance from the dependent (collapse the derived types) so it remains a leaf shared type.","Switch the hierarchy away from TPC (e.g. to TPT) if the shared-table-with-inheritance pattern is required."],"exampleFix":"// before\nmodelBuilder.Entity<Order>().UseTpcMappingStrategy();\nmodelBuilder.Entity<OrderDetail>().HasBaseType<OrderDetailBase>().ToTable(\"Orders\"); // shares + derives\n\n// after\nmodelBuilder.Entity<OrderDetail>().HasBaseType<OrderDetailBase>().ToTable(\"OrderDetails\");","handlingStrategy":"validation","validationCode":"bool TpcSharedDependentsAreLeaves(DbContext context)\n{\n    foreach (var root in context.Model.GetEntityTypes()\n        .Where(e => e.BaseType == null && e.GetMappingStrategy() == \"TPC\"))\n    {\n        foreach (var et in root.GetDerivedTypesInclusive())\n        {\n            var so = StoreObjectIdentifier.Create(et, StoreObjectType.Table);\n            if (so is null) continue;\n            bool sharesWithPrincipal = et.FindDeclaredReferencingRowInternalForeignKeys(so.Value).Any();\n            if (sharesWithPrincipal && et.GetDirectlyDerivedTypes().Any()) return false;\n        }\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try { _ = context.Model; }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"TPC\", StringComparison.Ordinal) && ex.Message.Contains(\"table-sharing\", StringComparison.Ordinal))\n{\n    throw new InvalidOperationException(\"A table-shared dependent in a TPC hierarchy has derived types. Move it to its own table or remove inheritance from it.\", ex);\n}","preventionTips":["In TPC, never add inheritance to entities that share a table with a principal.","Give owned/inline dependents their own tables before extending them with derived types.","Consider TPT if shared-table hierarchies are unavoidable."],"tags":["ef-core","model-validation","tpc","table-splitting","inheritance","relational"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}