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 configured with different delete behavior ('{deleteBehavior1}' and '{deleteBehavior2}'). What it means
Two foreign keys share a constraint name and table but have different DeleteBehavior values (translated to different referential actions such as Cascade vs Restrict). The database constraint can only encode one action.
Solutions
- Align both FKs to the same OnDelete behavior.
- Give the FKs distinct constraint names via HasConstraintName.
- Remove or remap the redundant FK if only one relationship is intended.
- If the duplicate is from TPT/splitting, consolidate the relationship definitions so a single DeleteBehavior applies.
Example fix
// before modelBuilder.Entity<Order>().HasOne(o => o.Customer).WithMany().OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity<Refund>().HasOne(r => r.Customer).WithMany().OnDelete(DeleteBehavior.NoAction); // both default to the same constraint name -> mismatch // after: align behaviors or rename modelBuilder.Entity<Order>().HasOne(o => o.Customer).WithMany().OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity<Refund>().HasOne(r => r.Customer).WithMany().OnDelete(DeleteBehavior.Cascade);
Defensive patterns
Strategy: validation
Validate before calling
// Verify DeleteBehavior consistency across colliding FKs.
var fks = modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys());
foreach (var fk in fks)
{
var name = fk.GetConstraintName();
foreach (var dup in fks.Where(o => o != fk && o.GetConstraintName() == name))
{
if (fk.DeleteBehavior != dup.DeleteBehavior)
Console.WriteLine($"DeleteBehavior mismatch on '{name}': {fk.DeleteBehavior} vs {dup.DeleteBehavior}.");
}
} Prevention
- Standardize DeleteBehavior across relationships to the same principal when they may share constraints.
- Review OnDelete calls during code review for consistency.
- Test model finalization in CI.
When it happens
Trigger: RelationalForeignKeyExtensions.AreCompatible with shouldThrow:true when RelationalModel.ToReferentialAction(foreignKey.DeleteBehavior) != ToReferentialAction(duplicateForeignKey.DeleteBehavior). Occurs when two relationships share a constraint name but one sets OnDelete(Cascade) and the other OnDelete(NoAction) (or ClientSetNull/Restrict).
Common situations: An owned entity and a regular reference to the same principal both ending up on the same columns; manually setting OnDelete differently on two relationships that default to the same constraint name; migration scaffolding after a DeleteBehavior change that conflicts with a pre-existing constraint.
Related errors
- The foreign keys on ' ' and on ' ' are both mapped to ' …
- The foreign keys on ' ' and on ' ' are both mapped to ' …
- The foreign keys on ' ' and on ' ' are both mapped to ' …
- The indexes on ' ' and on ' ' are both mapped to ' ', but…
- The indexes on ' ' and on ' ' are both mapped to ' . ', but…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/86f1220ceb3cd98f.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs:132
if (foreignKey.IsUnique != duplicateForeignKey.IsUnique)
{
return shouldThrow
? throw new InvalidOperationException(
RelationalStrings.DuplicateForeignKeyUniquenessMismatch(
foreignKey.Properties.Format(),
foreignKey.DeclaringEntityType.DisplayName(),
duplicateForeignKey.Properties.Format(),
duplicateForeignKey.DeclaringEntityType.DisplayName(),
foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(),
foreignKey.GetConstraintName(storeObject, principalTable.Value)))
: false;
}
var referentialAction = RelationalModel.ToReferentialAction(foreignKey.DeleteBehavior);
var duplicateReferentialAction = RelationalModel.ToReferentialAction(duplicateForeignKey.DeleteBehavior);
return referentialAction != duplicateReferentialAction
? shouldThrow
? throw new InvalidOperationException(
RelationalStrings.DuplicateForeignKeyDeleteBehaviorMismatch(
foreignKey.Properties.Format(),
foreignKey.DeclaringEntityType.DisplayName(),
duplicateForeignKey.Properties.Format(),
duplicateForeignKey.DeclaringEntityType.DisplayName(),
foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(),
foreignKey.GetConstraintName(storeObject, principalTable.Value),
referentialAction,
duplicateReferentialAction))
: false
: foreignKey.IsExcludedFromMigrations() == duplicateForeignKey.IsExcludedFromMigrations()
|| (shouldThrow
? throw new InvalidOperationException(
RelationalStrings.DuplicateForeignKeyExcludedFromMigrationsMismatch(
foreignKey.Properties.Format(),
foreignKey.DeclaringEntityType.DisplayName(),
duplicateForeignKey.Properties.Format(),
duplicateForeignKey.DeclaringEntityType.DisplayName(),View on GitHub (pinned to 3a2006ef56)