{"record":{"id":"f258c440a713b4dc","repo":"dotnet/efcore","slug":"both-entitytype-and-otherentitytype-are-ma","errorCode":null,"errorMessage":"Both '{entityType}' and '{otherEntityType}' are mapped to the table '{table}'. All the entity types in a non-TPH hierarchy (one that doesn't have a discriminator) must be mapped to different tables. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information.","messagePattern":"Both '(.+?)' and '(.+?)' are mapped to the table '(.+?)'\\. All the entity types in a non-TPH hierarchy \\(one that doesn't have a discriminator\\) must be mapped to different tables\\. See https://go\\.microsoft\\.com/fwlink/\\?linkid=2130430 for more information\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":2241,"sourceCode":"                    && 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()));\n                    case StoreObjectType.View:\n                        throw new InvalidOperationException(\n                            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)","sourceCodeStart":2223,"sourceCodeEnd":2259,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L2223-L2259","documentation":"Thrown inside ValidateNonTphMapping when two different entity types within the same non-TPH hierarchy resolve to the same Table StoreObjectIdentifier (collision detected via derivedTypes dictionary). In TPT/TPC every type must map to its own distinct table, so a clash is rejected.","triggerScenarios":"Two types in a TPT/TPC hierarchy both call ToTable(\"SameName\"), or default table-name conventions produce the same name for sibling types; sharing a table via explicit ToTable overrides in a non-TPH hierarchy.","commonSituations":"Manually mapping derived types to the same table while using TPT/TPC; rename/refactor that made two types collide on pluralization; trying to simulate TPH by forcing the same table under TPT.","solutions":["Give each entity type a unique table name in the non-TPH hierarchy.","Switch to TPH (UseTphMappingStrategy) if you genuinely want them all in one table.","Remove explicit ToTable overrides that force the collision and let conventions assign distinct names."],"exampleFix":"// before (TPT, clash)\nmodelBuilder.UseTptMappingStrategy();\nmodelBuilder.Entity<Customer>().ToTable(\"People\");\nmodelBuilder.Entity<Vendor>().ToTable(\"People\"); // throws 426\n\n// after\nmodelBuilder.Entity<Customer>().ToTable(\"Customers\");\nmodelBuilder.Entity<Vendor>().ToTable(\"Vendors\");","handlingStrategy":"validation","validationCode":"foreach (var root in modelBuilder.Model.GetEntityTypes().Where(t => t.BaseType == null))\n{\n    var strategy = root.GetMappingStrategy();\n    if (strategy != RelationalAnnotationNames.TptMappingStrategy\n        && strategy != RelationalAnnotationNames.TpcMappingStrategy) continue;\n    var tables = new HashSet<string>();\n    foreach (var et in root.GetDerivedTypesInclusive())\n    {\n        var so = StoreObjectIdentifier.Create(et, StoreObjectType.Table);\n        if (so != null && !tables.Add(so.Value.Name))\n            throw new InvalidOperationException($\"Table '{so.Value.Name}' used by multiple types in {root.DisplayName()} hierarchy.\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In TPT/TPC, give each type a unique ToTable name.","If a shared table is intended, use TPH instead.","Add a test that walks the hierarchy and asserts distinct table names per type."],"tags":["ef-core","model-validation","mapping","inheritance","tpt","tpc","tables"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}