dotnet/efcore · error · InvalidOperationException
The foreign keys {foreignKeyProperties1} on '{entityType1}'
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
Thrown by AreCompatible when two foreign keys share a name and are declared on the same dependent table, but reference different principal tables. A single database FK constraint can only point at one principal table, so EF rejects the ambiguous mapping.
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 dbf9771522)
Solutions
- Disambiguate the constraint names with explicit HasConstraintName so each points to its own principal cleanly.
- Reconcile the principal tables: if both FKs should target the same principal, fix the principal mapping.
- Split the dependent entity types onto separate tables if they genuinely reference different principals.
- Verify ToTable mapping for both principal entity types is what you intended.
Example fix
// before (OrderDetail shares table; FKs to Order vs Invoice, same constraint name)
modelBuilder.Entity<OrderDetail>().HasOne(d => d.Order)
.WithMany().HasForeignKey(d => d.OrderId).HasConstraintName("FK_Detail_Principal");
modelBuilder.Entity<OrderDetail>().HasOne(d => d.Invoice)
.WithMany().HasForeignKey(d => d.InvoiceId).HasConstraintName("FK_Detail_Principal");
// after
modelBuilder.Entity<OrderDetail>().HasOne(d => d.Order)
.WithMany().HasForeignKey(d => d.OrderId).HasConstraintName("FK_Detail_Order");
modelBuilder.Entity<OrderDetail>().HasOne(d => d.Invoice)
.WithMany().HasForeignKey(d => d.InvoiceId).HasConstraintName("FK_Detail_Invoice"); Defensive patterns
Strategy: validation
Validate before calling
// Verify FKs sharing a name also share the principal table
foreach (var g in modelBuilder.Model.GetEntityTypes().SelectMany(t => t.GetForeignKeys())
.GroupBy(fk => fk.GetConstraintName()))
{
var principalTables = g.Select(fk => fk.PrincipalEntityType.GetSchemaQualifiedTableName()).Distinct();
if (principalTables.Count() > 1)
throw new InvalidOperationException($"FK {g.Key} targets multiple principal tables.");
} Prevention
- When reusing an FK constraint name, ensure all instances target the same principal table.
- Give FKs to different principals distinct constraint names.
- Validate the model in tests to catch principal-table mismatches before runtime.
When it happens
Trigger: Two FKs on entity types sharing a dependent table resolve to one constraint name, but their PrincipalEntityType maps to a different principal table. Common in TPH/table-splitting where dependent types share a row but point at different principals.
Common situations: Table-splitting or TPH where one shared table has FKs to two different principal tables but the constraint names collide. Refactoring a principal entity to a different table after FK config was set.
Related errors
- The foreign keys {foreignKeyProperties1} on '{entityType1}'
- The foreign keys {foreignKeyProperties1} on '{entityType1}'
- The foreign keys {foreignKeyProperties1} on '{entityType1}'
- The foreign keys {foreignKeyProperties1} on '{entityType1}'
- The foreign keys {foreignKeyProperties1} on '{entityType1}'
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/afce015eb3424b79.
Report an issue: GitHub.