dotnet/efcore · error · InvalidOperationException

Explicitly named default constraints cannot be used with…

Error message

Explicitly named default constraints cannot be used with TPC inheritance or entity splitting. Constraint name: '{explicitDefaultConstraintName}'.

What it means

The companion to [458]: when a property maps to multiple tables (TPC or entity splitting) AND an explicit default-constraint name HAS been configured, EF still throws ExplicitDefaultConstraintNamesNotSupportedForTpc. A single explicit name cannot be reused across tables (names must be unique), and EF does not yet support per-table explicit names, so even an explicitly named default constraint is unsupported in these scenarios (issue #27970).

Solutions

  1. Remove the default value/SQL (and the explicit name) from the shared property so no default constraint is generated on multiple tables.
  2. Remap the property to a single table (switch TPC -> TPH, or un-split) if the default is essential.
  3. Move the default-bearing property onto a non-shared entity so it occupies one table.
  4. Await issue #27970 for per-table explicit default-constraint name support.

Example fix

// before — explicit default-constraint name on a TPC-shared property -> [459]
modelBuilder.Entity<Animal>().UseTpcMapping()
    .Property(a => a.Legs)
    .HasDefaultValue(4)
    .HasDefaultConstraintName("DF_Animal_Legs");

// after — no default constraint on the shared property
modelBuilder.Entity<Animal>().UseTpcMapping()
    .Property(a => a.Legs);
// set Animal.Legs = 4 in the constructor/OnModelCreating seed data instead
Defensive patterns

Strategy: validation

Validate before calling

// Detect explicitly-named default constraints on properties mapped to multiple tables.
static IEnumerable<IProperty> PropertiesWithExplicitNamedDefaultsOnMultiTable(IModel model)
    => model.GetEntityTypes()
        .SelectMany(et => et.GetProperties())
        .Where(p => p.GetMappedStoreObjects(StoreObjectType.Table).Count() > 1
                    && p.GetDefaultConstraintNameConfigurationSource() is not null);

Prevention

When it happens

Trigger: Setting .HasDefaultValue(v) (or HasDefaultValueSql) together with an explicit default-constraint name (.HasDefaultConstraintName("DF_X")) on a property that maps to multiple tables under TPC inheritance or entity splitting.

Common situations: Trying to 'fix' [458] by naming the constraint; copying default-constraint naming from TPH code into a TPC hierarchy; split entities with named defaults.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/7d4579b8b16800ea. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs:772

        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(
        IConventionEntityType entityType,
        Dictionary<string, (IConventionTrigger, StoreObjectIdentifier)> triggers,
        in StoreObjectIdentifier storeObject,
        int maxLength)

View on GitHub (pinned to 3a2006ef56)