dotnet/efcore · error · InvalidOperationException
The keys on ' ' and on ' ' are both mapped to ' ', but on…
Error message
The keys {keyProperties1} on '{entityType1}' and {keyProperties2} on '{entityType2}' are both mapped to '{keyName}', but on different tables ('{table1}' and '{table2}'). What it means
Two keys share the same database name but their declaring entities are mapped to different tables, so at least one cannot produce a column list for the store object. One key constraint name cannot span two tables.
Solutions
- Give each key a distinct name via HasName(...) on the key.
- Ensure both keys are mapped to the same table if the shared name is intentional.
- Remove the redundant key definition.
- When changing inheritance strategy, regenerate constraint names.
Example fix
// before: TPT, both default to 'PK_Base'
modelBuilder.Entity<Base>().ToTable("Base").HasKey(b => b.Id);
modelBuilder.Entity<Derived>().ToTable("Derived").HasKey(d => d.Id);
// after: rename one
modelBuilder.Entity<Derived>().ToTable("Derived").HasKey(d => d.Id).HasName("PK_Derived"); Defensive patterns
Strategy: validation
Validate before calling
// Find keys whose names collide across different tables.
var keys = modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetDeclaredKeys());
foreach (var k in keys)
{
var name = k.GetName();
foreach (var dup in keys.Where(o => o != k && o.GetName() == name
&& o.DeclaringEntityType.GetSchemaQualifiedTableName() != k.DeclaringEntityType.GetSchemaQualifiedTableName()))
{
Console.WriteLine($"Key name '{name}' used on two tables: {k.DeclaringEntityType.Name} and {dup.DeclaringEntityType.Name}.");
}
} Prevention
- Set explicit HasName for keys in TPT/Tpc hierarchies.
- After switching inheritance strategies, regenerate key constraint names.
- Add a model validation test to CI.
When it happens
Trigger: RelationalKeyExtensions.AreCompatible with shouldThrow:true when key.Properties.GetColumnNames(storeObject) or duplicateKey.Properties.GetColumnNames(storeObject) returns null. Common in TPT/Tpc inheritance where the same key constraint name is reused across the base and derived tables.
Common situations: TPT hierarchies with default key naming; explicit HasKeyName reuse across entities mapped to different tables; switching mapping strategies without renaming constraints.
Related errors
- The foreign keys on ' ' and on ' ' are both mapped to ' …
- The indexes on ' ' and on ' ' are both mapped to ' ', but…
- The keys on ' ' and on ' ' are both mapped to ' . ', but…
- Both ' ' and ' ' are mapped to the table ' '. All the…
- Both ' ' and ' ' are mapped to the stored procedure ' '…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/1ccc47234be4777d.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Metadata/Internal/RelationalKeyExtensions.cs:33
{
/// <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>
public static bool AreCompatible(
this IReadOnlyKey key,
IReadOnlyKey duplicateKey,
in StoreObjectIdentifier storeObject,
bool shouldThrow)
{
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(),View on GitHub (pinned to 3a2006ef56)