{"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/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L2268-L2304","documentation":"Thrown at the end of ValidateNonTphMapping when, in a TPC hierarchy, the root entity has row internal foreign keys (shares its table with a principal), and more than one derived type exists (derivedTypes.Count > 1). TPC requires each concrete type to be fully self-contained, so a root that shares a table while being inherited by multiple types is unsupported.","triggerScenarios":"The root of a TPC hierarchy participates in table sharing (FindRowInternalForeignKeys on the root store object returns any) and has multiple derived concrete types mapping into the hierarchy.","commonSituations":"An abstract/concrete root that owns or shares a table with another entity, combined with multiple derived types under UseTpcMappingStrategy(); refactor that added a derived type to an already-splitting TPC root.","solutions":["Stop table sharing at the TPC root (remove the ownership/splitting or map owned data separately).","Reduce to a single derived type (not usually intended — prefer the first option).","Switch the hierarchy from TPC to TPT/TPH if table sharing at the root is required."],"exampleFix":"// before (TPC, root shares table, multiple derived)\nmodelBuilder.Entity<Person>().ToTable(\"People\").OwnsOne(p => p.Audit, a => a.ToTable(\"People\"));\nmodelBuilder.UseTpcMappingStrategy();\n// Customer and Vendor derive from Person -> throws 430\n\n// after - no table sharing at root under TPC\nmodelBuilder.Entity<Person>().OwnsOne(p => p.Audit, a => a.ToTable(\"People_Audit\"));","handlingStrategy":"validation","validationCode":"foreach (var root in modelBuilder.Model.GetEntityTypes().Where(t => t.BaseType == null))\n{\n    if (root.GetMappingStrategy() != RelationalAnnotationNames.TpcMappingStrategy) continue;\n    foreach (StoreObjectType sot in new[] { StoreObjectType.Table, StoreObjectType.View })\n    {\n        var rootSo = StoreObjectIdentifier.Create(root, sot);\n        if (rootSo == null) continue;\n        if (!root.FindRowInternalForeignKeys(rootSo.Value).Any()) continue;\n        var derivedCount = root.GetDerivedTypesInclusive().Count();\n        if (derivedCount > 1)\n            throw new InvalidOperationException($\"Root {root.DisplayName()} shares {sot} under TPC but has {derivedCount} types in hierarchy.\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid table sharing at the TPC root when there are multiple derived types.","Refactor owned/split data off the root, or switch strategy.","Add a model test covering TPC + sharing scenarios."],"tags":["ef-core","model-validation","mapping","inheritance","tpc","table-splitting"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}