{"record":{"id":"8e81d5fafd7cb37e","repo":"dotnet/efcore","slug":"the-entity-type-dependenttype-is-mapped-to-s-8e81d5","errorCode":null,"errorMessage":"The entity type '{dependentType}' is mapped to '{storeObject}'. However one of its derived types '{derivedType}' is mapped to '{otherStoreObject}'. Hierarchies using table-sharing cannot be mapped using the TPC mapping strategy.","messagePattern":"The entity type '(.+?)' is mapped to '(.+?)'\\. However one of its derived types '(.+?)' is mapped to '(.+?)'\\. Hierarchies using table-sharing cannot be mapped using the TPC mapping strategy\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":2286,"sourceCode":"                            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\n            && rootEntityType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy)\n        {\n            var derivedTypePair = derivedTypes.First(kv => kv.Value != rootEntityType);\n            throw new InvalidOperationException(\n                RelationalStrings.TpcTableSharingDependent(\n                    rootEntityType.DisplayName(),\n                    rootStoreObject.Value.DisplayName(),\n                    derivedTypePair.Value.DisplayName(),\n                    derivedTypePair.Key.DisplayName()));\n        }\n    }\n\n    private static void ValidateTphMapping(IEntityType rootEntityType, StoreObjectType storeObjectType)\n    {\n        var isSproc = storeObjectType is StoreObjectType.DeleteStoredProcedure\n            or StoreObjectType.InsertStoredProcedure\n            or StoreObjectType.UpdateStoredProcedure;\n        var rootSproc = isSproc ? StoredProcedure.FindDeclaredStoredProcedure(rootEntityType, storeObjectType) : null;\n        var rootId = StoreObjectIdentifier.Create(rootEntityType, storeObjectType);\n        foreach (var entityType in rootEntityType.GetDerivedTypes())\n        {\n            var entityId = StoreObjectIdentifier.Create(entityType, storeObjectType);","sourceCodeStart":2268,"sourceCodeEnd":2304,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L2268-L2304","documentation":"Also in ValidateNonTphMapping for TPC: if the root entity has row-internal foreign keys (i.e. table-sharing) and more than one entity type in the hierarchy is mapped, the model is rejected because TPC requires each concrete type in its own table and cannot represent a shared root table across a hierarchy. The first non-root derived mapping is reported.","triggerScenarios":"Root entity has TPC strategy, FindRowInternalForeignKeys returns at least one row-internal FK on the root store object, and derivedTypes.Count > 1 (multiple hierarchy members mapped). Typically appears when the root table is shared with another entity but you still want TPC over its derived types.","commonSituations":"Adding .UseTpcMappingStrategy() to an entity that also participates in table sharing (e.g. owned/inline or joint table) with derived types; migrating a shared-table design to TPC.","solutions":["Break the table sharing on the root so FindRowInternalForeignKeys is empty: give the root (and any shared principal) distinct tables.","Switch the hierarchy to TPT or TPH which can coexist with shared root tables.","Collapse the hierarchy so there is only one mapped type (no derived mappings)."],"exampleFix":"// before\nmodelBuilder.Entity<Customer>().UseTpcMappingStrategy().ToTable(\"Contacts\"); // Contacts shared\n\n// after\nmodelBuilder.Entity<Customer>().UseTpcMappingStrategy().ToTable(\"Customers\"); // exclusive table","handlingStrategy":"validation","validationCode":"bool TpcRootNotTableSharedWithHierarchy(DbContext context)\n{\n    foreach (var root in context.Model.GetEntityTypes()\n        .Where(e => e.BaseType == null && e.GetMappingStrategy() == \"TPC\"))\n    {\n        var so = StoreObjectIdentifier.Create(root, StoreObjectType.Table);\n        if (so is null) continue;\n        bool shares = root.FindRowInternalForeignKeys(so.Value).Any();\n        int mappedCount = root.GetDerivedTypesInclusive().Count(d => StoreObjectIdentifier.Create(d, StoreObjectType.Table) != null);\n        if (shares && mappedCount > 1) return false;\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) && ex.Message.Contains(\"derived\", StringComparison.Ordinal))\n{\n    throw new InvalidOperationException(\"A TPC root shares its table while multiple derived types are mapped. Break the sharing or switch to TPT.\", ex);\n}","preventionTips":["Do not combine .UseTpcMappingStrategy() with table-shared roots.","Reserve TPC for hierarchies where every type lives in its own dedicated table.","Validate the model in a unit test before deploying."],"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"}