dotnet/efcore · error · InvalidOperationException

The keys {keyProperties1} on '{entityType1}' and {keyPropert

Error message

The keys {keyProperties1} on '{entityType1}' and {keyProperties2} on '{entityType2}' are both mapped to '{table}.{keyName}', but with different columns ({columnNames1} and {columnNames2}).

What it means

Thrown by RelationalKeyExtensions.AreCompatible when two keys share the same name AND table but resolve to different column lists. A named key constraint is one physical object, so EF requires the property->column mapping to be identical across all keys sharing the name.

Source

Thrown at src/EFCore.Relational/Metadata/Internal/RelationalKeyExtensions.cs:45

    {
        var columnNames = key.Properties.GetColumnNames(storeObject);
        var duplicateColumnNames = duplicateKey.Properties.GetColumnNames(storeObject);
        return columnNames == null
            || duplicateColumnNames == null
                ? shouldThrow
                    ? throw new InvalidOperationException(
                        RelationalStrings.DuplicateKeyTableMismatch(
                            key.Properties.Format(),
                            key.DeclaringEntityType.DisplayName(),
                            duplicateKey.Properties.Format(),
                            duplicateKey.DeclaringEntityType.DisplayName(),
                            key.GetName(storeObject),
                            key.DeclaringEntityType.GetSchemaQualifiedTableName(),
                            duplicateKey.DeclaringEntityType.GetSchemaQualifiedTableName()))
                    : false
                : columnNames.SequenceEqual(duplicateColumnNames)
                || (shouldThrow
                    ? throw new InvalidOperationException(
                        RelationalStrings.DuplicateKeyColumnMismatch(
                            key.Properties.Format(),
                            key.DeclaringEntityType.DisplayName(),
                            duplicateKey.Properties.Format(),
                            duplicateKey.DeclaringEntityType.DisplayName(),
                            key.DeclaringEntityType.GetSchemaQualifiedTableName(),
                            key.GetName(storeObject),
                            key.Properties.FormatColumns(storeObject),
                            duplicateKey.Properties.FormatColumns(storeObject)))
                    : false);
    }

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>

View on GitHub (pinned to dbf9771522)

Solutions

  1. Align the key properties and their HasColumnName on both entity types so the resolved column lists match.
  2. Give each key a distinct name with HasName.
  3. Move the key declaration to a single entity type so there is one source of truth.
  4. Confirm equality with key.Properties.GetColumnNames(storeObject) on both sides.

Example fix

// before
modelBuilder.Entity<Account>().HasAlternateKey(a => a.LedgerId).HasName("AK_Ledger");
modelBuilder.Entity<Txn>().HasAlternateKey(t => t.JournalId).HasName("AK_Ledger"); // same table, diff cols -> throws

// after
modelBuilder.Entity<Txn>().HasAlternateKey(t => t.LedgerId).HasName("AK_Ledger");
Defensive patterns

Strategy: validation

Validate before calling

static bool KeysColumnMatch(IReadOnlyKey a, IReadOnlyKey b, StoreObjectIdentifier so)
    => a.GetName(so) == b.GetName(so)
        && a.Properties.GetColumnNames(so) is { } ca
        && b.Properties.GetColumnNames(so) is { } cb
        && ca.SequenceEqual(cb);

Prevention

When it happens

Trigger: Lines 43-54: both column lists are non-null but columnNames.SequenceEqual(duplicateColumnNames) is false. Produced when HasKey on two table-sharing entity types uses the same name but maps to different properties/columns (e.g. via HasColumnName divergence).

Common situations: Table splitting where each entity declares a same-named key over different properties; a property renamed at column level on one entity without updating the key; composite keys where one side added/removed a property.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/5ccb88433db5b3c7. Report an issue: GitHub.