dotnet/efcore · error · InvalidOperationException
A seed entity for entity type
Error message
A seed entity for entity type '{entityType}' has the same key value as another seed entity mapped to the same table '{table}'. Key values should be unique across seed entities. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting values. What it means
Thrown by MigrationsModelDiffer while diffing the model to build seed-data modification commands. Two seed entities that map to the same (non-shared) table resolve to the same key, so EF cannot decide which row to insert/update. The non-sensitive form deliberately omits the key value so that data is not leaked into logs; enable EnableSensitiveDataLogging to see it.
Solutions
- Inspect every HasData block for the named entity type and make each key value unique.
- Temporarily call optionsBuilder.EnableSensitiveDataLogging() to print the conflicting key value and locate both entries.
- If the collision is intentional (merge), remove one of the duplicate seed entries so only one row is produced.
- For shared-table mappings confirm you actually intend one row; otherwise split the entities onto different tables.
Example fix
// before
modelBuilder.Entity<Customer>()
.HasData(
new Customer { Id = 1, Name = "Acme" },
new Customer { Id = 1, Name = "Globex" }); // duplicate Id
// after
modelBuilder.Entity<Customer>()
.HasData(
new Customer { Id = 1, Name = "Acme" },
new Customer { Id = 2, Name = "Globex" }); Defensive patterns
Strategy: validation
Validate before calling
// Before calling HasData, assert key uniqueness per entity type
static void AssertSeedKeysUnique<TEntity>(
IEnumerable<TEntity> seed,
Func<TEntity, object> keySelector)
{
var dupes = seed.GroupBy(keySelector)
.Where(g => g.Count() > 1)
.ToList();
if (dupes.Count > 0)
throw new InvalidOperationException(
$"Duplicate seed keys for {typeof(TEntity).Name}: " +
string.Join(", ", dupes.Select(g => g.Key)));
}
// usage in OnModelCreating
AssertSeedKeysUnique(customers, c => c.Id); Type guard
// Narrow anonymous seed rows to a distinct-by-key set before HasData
static T[] DistinctByKey<T, TKey>(IEnumerable<T> src, Func<T, TKey> key)
=> src.GroupBy(key).Select(g => g.First()).ToArray(); Prevention
- Centralize seed data in one file per entity and review it during code review.
- Add a unit test that loads the model and asserts every HasData set is key-unique.
- Run 'dotnet ef migrations add' in CI to surface seed collisions before deploy.
When it happens
Trigger: ModelCreating HasData(...) for one entity type contains two entries whose key properties evaluate equal, or two entity types mapped to the same table seed colliding keys. Reached when 'dotnet ef migrations add' (or any code path that runs the differ) processes the model.
Common situations: Copy-pasted seed rows with unchanged Id; integer key constants that collide; TPH inheritance where base and derived entities seed the same discriminator key; seeding regenerated after a key-column rename where old seed values were not updated.
Related errors
- A seed entity for entity type
- A seed entity for entity type
- The data insertion operation on
- The number of column types
- The number of key values
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/b7dc67f3464cf552.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs:1936
if (!keyFound)
{
continue;
}
if (identityMap.FindCommand(key) is { } existingCommand)
{
if (!table.IsShared)
{
if (sensitiveLoggingEnabled)
{
throw new InvalidOperationException(
RelationalStrings.DuplicateSeedDataSensitive(
entityType.DisplayName(),
BuildValuesString(key),
table.SchemaQualifiedName));
}
throw new InvalidOperationException(
RelationalStrings.DuplicateSeedData(
entityType.DisplayName(),
table.SchemaQualifiedName));
}
command = existingCommand;
}
else
{
command = CommandBatchPreparerDependencies.ModificationCommandFactory.CreateNonTrackedModificationCommand(
new NonTrackedModificationCommandParameters(table, sensitiveLoggingEnabled));
command.EntityState = initialState;
identityMap.Add(key, command);
}
foreach (var columnMapping in mapping.ColumnMappings)
{View on GitHub (pinned to 3a2006ef56)