dotnet/efcore · error · InvalidOperationException

The foreign keys on ' ' and on ' ' are both mapped to ' …

Error message

The foreign keys {foreignKeyProperties1} on '{entityType1}' and {foreignKeyProperties2} on '{entityType2}' are both mapped to '{table}.{foreignKeyName}', but referencing different principal tables ('{principalTable1}' and '{principalTable2}').

What it means

Two foreign keys are mapped to the same constraint on the same table but reference different principal tables, which is impossible for a single FK constraint. AreCompatible throws DuplicateForeignKeyPrincipalTableMismatch when the principal StoreObjectIdentifiers differ or cannot be resolved.

Solutions

  1. Remove the shared HasConstraintName override so each FK gets a distinct default name based on its principal.
  2. If overrides are intentional, ensure each name is unique per principal-table combination.
  3. Verify the principal entity of each relationship is the one you expect (check HasOne/WithMany targets).

Example fix

// before
modelBuilder.Entity<Loan>()
    .HasOne(l => l.Account).WithMany().HasForeignKey(l => l.AccountId)
    .HasConstraintName("FK_Account");
modelBuilder.Entity<Loan>()
    .HasOne(l => l.Branch).WithMany().HasForeignKey(l => l.BranchId)
    .HasConstraintName("FK_Account");

// after
modelBuilder.Entity<Loan>()
    .HasOne(l => l.Branch).WithMany().HasForeignKey(l => l.BranchId)
    .HasConstraintName("FK_Loan_Branch");
Defensive patterns

Strategy: validation

Validate before calling

// Ensure FKs sharing a name on the same table point to the same principal table
var conflicts = modelBuilder.Model.GetEntityTypes()
    .SelectMany(e => e.GetDeclaredForeignKeys())
    .GroupBy(fk => (fk.GetConstraintName(), fk.DeclaringEntityType.GetSchemaQualifiedTableName()))
    .Where(g => g.Select(fk => fk.PrincipalEntityType.GetSchemaQualifiedTableName()).Distinct().Count() > 1);
if (conflicts.Any()) throw new InvalidOperationException("FKs sharing a constraint name reference different principal tables.");

Prevention

When it happens

Trigger: Two FKs on the same table both manually named the same via HasConstraintName but pointing at different principal entities/tables; refactor that changed which entity an FK targets without renaming the constraint.

Common situations: Two relationships on one entity (e.g. OwnerId and CustomerId) where the developer forced the same FK constraint name; TPH inheritance where base and derived declare FKs that collide.

Related errors


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

Appendix: source

Thrown at src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs:67

                        duplicateForeignKey.DeclaringEntityType.DisplayName(),
                        principalTable.HasValue
                            ? foreignKey.GetConstraintName(storeObject, principalTable.Value)
                            : foreignKey.GetDefaultName(),
                        foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(),
                        duplicateForeignKey.DeclaringEntityType.GetSchemaQualifiedTableName()))
                : false;
        }

        if (principalTable is null
            || duplicatePrincipalTable is null
            || principalTable != duplicatePrincipalTable
            || foreignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value)
                is not { } principalColumns
            || duplicateForeignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value)
                is not { } duplicatePrincipalColumns)
        {
            return shouldThrow
                ? throw new InvalidOperationException(
                    RelationalStrings.DuplicateForeignKeyPrincipalTableMismatch(
                        foreignKey.Properties.Format(),
                        foreignKey.DeclaringEntityType.DisplayName(),
                        duplicateForeignKey.Properties.Format(),
                        duplicateForeignKey.DeclaringEntityType.DisplayName(),
                        foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(),
                        principalTable.HasValue
                            ? foreignKey.GetConstraintName(storeObject, principalTable.Value)
                            : foreignKey.GetDefaultName(),
                        principalType.GetSchemaQualifiedTableName(),
                        duplicatePrincipalType.GetSchemaQualifiedTableName()))
                : false;
        }

        if (!columnNames.SequenceEqual(duplicateColumnNames))
        {
            return shouldThrow
                ? throw new InvalidOperationException(

View on GitHub (pinned to 3a2006ef56)