dotnet/efcore · error · InvalidOperationException
Named default constraints cannot be used with TPC or entity…
Error message
Named default constraints cannot be used with TPC or entity splitting if they result in non-unique constraint names. Constraint name: '{constraintNameCandidate}'. What it means
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).
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.
Example fix
// before — TPC + default value on a property shared across tables -> [458]
modelBuilder.Entity<Animal>().UseTpcMapping()
.Property(a => a.Legs).HasDefaultValue(4);
// after — drop the default (or remap to a single table / TPH)
modelBuilder.Entity<Animal>().UseTpcMapping()
.Property(a => a.Legs);
// (apply the default at insert time in code instead) Defensive patterns
Strategy: validation
Validate before calling
// Detect properties with defaults that map to multiple tables (TPC/splitting) without an explicit name.
static IEnumerable<IProperty> PropertiesWithClashingImplicitDefaults(IModel model)
=> model.GetEntityTypes()
.SelectMany(et => et.GetProperties())
.Where(p => p.GetMappedStoreObjects(StoreObjectType.Table).Count() > 1
&& p.GetDefaultConstraintNameConfigurationSource() is null
&& (p.GetDefaultValue() is not null || p.GetDefaultValueSql() is not null)); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Adopting TPC mapping on a hierarchy whose base properties have defaults; entity splitting combined with default values; introducing .HasDefaultValue after migrating to TPC.
Related errors
- Explicitly named default constraints cannot be used with…
- Both ' ' and ' ' are mapped to the table ' '. All the…
- Both ' ' and ' ' are mapped to the stored procedure ' '…
- Both ' ' and ' ' are mapped to the view ' '. All the entity…
- ' ' cannot be set for ' ' at the same time as ' '. Remove…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/8373bde312764809.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs:768
private static string? TryUniquifyDefaultConstraint(
IConventionProperty property,
string constraintName,
string? schema,
Dictionary<(string, string?), (IConventionProperty, StoreObjectIdentifier)> defaultConstraints,
in StoreObjectIdentifier storeObject,
int maxLength)
{
var mappedTables = property.GetMappedStoreObjects(StoreObjectType.Table);
if (mappedTables.Count() > 1)
{
// For TPC and some entity splitting scenarios we end up with multiple tables having to define the constraint.
// Since constraint name has to be unique, we can't keep the same name for all
// Disabling this scenario until we have better way to configure the constraint name
// see issue #27970
if (property.GetDefaultConstraintNameConfigurationSource() == null)
{
throw new InvalidOperationException(
RelationalStrings.ImplicitDefaultNamesNotSupportedForTpcWhenNamesClash(constraintName));
}
throw new InvalidOperationException(
RelationalStrings.ExplicitDefaultConstraintNamesNotSupportedForTpc(constraintName));
}
if (property.Builder.CanSetAnnotation(RelationalAnnotationNames.DefaultConstraintName, null))
{
constraintName = Uniquifier.Uniquify(constraintName, defaultConstraints, n => (n, schema), maxLength);
property.Builder.HasAnnotation(RelationalAnnotationNames.DefaultConstraintName, constraintName);
return constraintName;
}
return null;
}
private void UniquifyTriggerNames(View on GitHub (pinned to 3a2006ef56)