dotnet/efcore · error · InvalidOperationException
The table ' ' cannot be used for entity type ' ' since it…
Error message
The table '{table}' cannot be used for entity type '{entityType}' since it is being used for entity type '{otherEntityType}' and the name '{keyName}' of the primary key {primaryKey} does not match the name '{otherName}' of the primary key {otherPrimaryKey}. What it means
Thrown when entity types sharing a table have different primary-key names for that table (computed via key.GetName(table)). The validator ensures every sharing type agrees on the PK constraint name; a mismatch would produce conflicting DDL/migration. Names are compared with key.GetName(table) for each connected entity type.
Solutions
- Unify the PK constraint name across all entity types sharing the table: .HasKey(e => e.Id).HasName("PK_Users") on every sharing entity (or remove all explicit HasName so they fall back to the same convention).
- If the names truly must differ, the types must not share a table — remap one of them.
- Generate/check a migration to confirm the resulting PK constraint name.
Example fix
// before
builder.Entity<Customer>().HasKey(c => c.Id).HasName("PK_Customers");
builder.Entity<Customer>().ToTable("Users");
builder.Entity<User>().ToTable("Users"); // default PK name
// after
builder.Entity<Customer>().HasKey(c => c.Id).HasName("PK_Users");
builder.Entity<User>().HasKey(u => u.Id).HasName("PK_Users"); Defensive patterns
Strategy: validation
Validate before calling
var byTable = model.GetEntityTypes().Where(e => e.GetTableName() != null).GroupBy(e => e.GetTableName());
foreach (var grp in byTable)
{
var names = grp.Select(e => (e, e.FindPrimaryKey()?.GetName(StoreObjectIdentifier.Table(grp.Key)))).ToList();
var distinct = names.Where(n => n.Item2 != null).Select(n => n.Item2).Distinct().ToList();
if (distinct.Count > 1)
Console.WriteLine($"Table '{grp.Key}' has multiple PK names: {string.Join(", ", distinct)}");
} Prevention
- Either never set explicit PK names on shared tables, or set the same HasName on every sharing type.
- When migrating an existing database, copy the canonical PK constraint name into the model.
- Review PK names whenever you consolidate entity types onto one table.
When it happens
Trigger: Two entity types mapped to the same table where one has been given a custom PK name via .HasKey(...).HasName("PK_Foo") (or via HasPrincipalKey name on the relationship) and the other uses a different name. Often emerges in TPH/TPT where conventions assign names differently, or when migrations add explicit names.
Common situations: Hand-named PK constraints on one entity but not the other; merging two contexts that share a table; explicit constraint names from a migration that did not propagate to siblings.
Related errors
- Entity type ' ' is an optional dependent using table…
- The property ' ' cannot be configured as…
- The table ' ' cannot be used for entity type ' ' since it…
- The table ' ' cannot be used for entity type ' ' since it…
- The table ' ' cannot be used for entity type ' ' since it…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/373d24936e87abd0.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:1219
while (typesToValidate.Count > 0)
{
var entityType = typesToValidate.Dequeue();
var key = entityType.FindPrimaryKey();
var comment = entityType.GetComment();
var isExcluded = entityType.IsTableExcludedFromMigrations(table);
var typesToValidateLeft = typesToValidate.Count;
var directlyConnectedTypes = unvalidatedTypes.Where(unvalidatedType =>
entityType.IsAssignableFrom(unvalidatedType)
|| IsIdentifyingPrincipal(unvalidatedType, entityType));
foreach (var nextEntityType in directlyConnectedTypes)
{
if (key != null)
{
var otherKey = nextEntityType.FindPrimaryKey()!;
if (key.GetName(table) != otherKey.GetName(table))
{
throw new InvalidOperationException(
RelationalStrings.IncompatibleTableKeyNameMismatch(
table.DisplayName(),
entityType.DisplayName(),
nextEntityType.DisplayName(),
key.GetName(table),
key.Properties.Format(),
otherKey.GetName(table),
otherKey.Properties.Format()));
}
}
var nextComment = nextEntityType.GetComment();
if (comment != null)
{
if (nextComment != null
&& !comment.Equals(nextComment, StringComparison.Ordinal))
{
throw new InvalidOperationException(View on GitHub (pinned to 3a2006ef56)