{"record":{"id":"8373bde312764809","repo":"dotnet/efcore","slug":"named-default-constraints-cannot-be-used-with-tpc","errorCode":null,"errorMessage":"Named default constraints cannot be used with TPC or entity splitting if they result in non-unique constraint names. Constraint name: '{constraintNameCandidate}'.","messagePattern":"Named default constraints cannot be used with TPC or entity splitting if they result in non-unique constraint names\\. Constraint name: '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs","lineNumber":768,"sourceCode":"\n    private static string? TryUniquifyDefaultConstraint(\n        IConventionProperty property,\n        string constraintName,\n        string? schema,\n        Dictionary<(string, string?), (IConventionProperty, StoreObjectIdentifier)> defaultConstraints,\n        in StoreObjectIdentifier storeObject,\n        int maxLength)\n    {\n        var mappedTables = property.GetMappedStoreObjects(StoreObjectType.Table);\n        if (mappedTables.Count() > 1)\n        {\n            // For TPC and some entity splitting scenarios we end up with multiple tables having to define the constraint.\n            // Since constraint name has to be unique, we can't keep the same name for all\n            // Disabling this scenario until we have better way to configure the constraint name\n            // see issue #27970\n            if (property.GetDefaultConstraintNameConfigurationSource() == null)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.ImplicitDefaultNamesNotSupportedForTpcWhenNamesClash(constraintName));\n            }\n\n            throw new InvalidOperationException(\n                RelationalStrings.ExplicitDefaultConstraintNamesNotSupportedForTpc(constraintName));\n        }\n\n        if (property.Builder.CanSetAnnotation(RelationalAnnotationNames.DefaultConstraintName, null))\n        {\n            constraintName = Uniquifier.Uniquify(constraintName, defaultConstraints, n => (n, schema), maxLength);\n            property.Builder.HasAnnotation(RelationalAnnotationNames.DefaultConstraintName, constraintName);\n            return constraintName;\n        }\n\n        return null;\n    }\n\n    private void UniquifyTriggerNames(","sourceCodeStart":750,"sourceCodeEnd":786,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs#L750-L786","documentation":"SharedTableConvention.TryUniquifyDefaultConstraint fires when a property with a default value/SQL maps to more than one table (TPC inheritance or entity splitting). Default-constraint names must be unique per database; EF would otherwise generate the SAME implicit name for each table, causing a clash. When no explicit default-constraint-name configuration source is present, EF cannot disambiguate and throws rather than emit invalid DDL (tracked by issue #27970).","triggerScenarios":"A property carrying .HasDefaultValue(...) / .HasDefaultValueSql(...) in a TPC-mapped hierarchy or a split entity, where the property maps to multiple tables and the implicit (generated) default-constraint name collides across them, with no explicit name configured.","commonSituations":"Adopting TPC mapping on a hierarchy whose base properties have defaults; entity splitting combined with default values; introducing .HasDefaultValue after migrating to TPC.","solutions":["Remove the default value/SQL from the shared property, or remap so the property lives on a single table (e.g. switch from TPC to TPH).","Provide an explicit, per-table-unique default-constraint name only if your scenario is supported (see [459] — currently still unsupported for TPC/splitting), otherwise prefer removing the default.","Move the default-bearing property to a non-shared entity so it maps to one table.","Track issue #27970 for per-table explicit default-constraint name support."],"exampleFix":"// before — TPC + default value on a property shared across tables -> [458]\nmodelBuilder.Entity<Animal>().UseTpcMapping()\n    .Property(a => a.Legs).HasDefaultValue(4);\n\n// after — drop the default (or remap to a single table / TPH)\nmodelBuilder.Entity<Animal>().UseTpcMapping()\n    .Property(a => a.Legs);\n// (apply the default at insert time in code instead)","handlingStrategy":"validation","validationCode":"// Detect properties with defaults that map to multiple tables (TPC/splitting) without an explicit name.\nstatic IEnumerable<IProperty> PropertiesWithClashingImplicitDefaults(IModel model)\n    => model.GetEntityTypes()\n        .SelectMany(et => et.GetProperties())\n        .Where(p => p.GetMappedStoreObjects(StoreObjectType.Table).Count() > 1\n                    && p.GetDefaultConstraintNameConfigurationSource() is null\n                    && (p.GetDefaultValue() is not null || p.GetDefaultValueSql() is not null));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid .HasDefaultValue/.HasDefaultValueSql on properties shared across multiple tables under TPC/splitting.","Switch to TPH or un-split if the default is essential.","Track issue #27970 for per-table default-constraint naming."],"tags":["default-constraints","tpc","entity-splitting","conventions"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}