dotnet/efcore · error · InvalidOperationException
The keyless entity type '{entityType}' was configured to use
Error message
The keyless entity type '{entityType}' was configured to use '{sproc}'. An entity type requires a primary key to be able to be mapped to a stored procedure. What it means
Thrown when a keyless entity type (no primary key, HasNoKey) is mapped to a stored procedure. Stored procedures require a primary key to identify rows for insert/update/delete operations; the validator rejects a null primary key in ValidateSproc.
Source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:573
mappedTypes[0].DisplayName(),
mappedType.DisplayName(),
storedProcedure.DisplayName()));
}
}
}
private static void ValidateSproc(
IStoredProcedure sproc,
string mappingStrategy,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
var entityType = sproc.EntityType;
var storeObjectIdentifier = sproc.GetStoreIdentifier();
var primaryKey = entityType.FindPrimaryKey();
if (primaryKey == null)
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureKeyless(
entityType.DisplayName(), storeObjectIdentifier.DisplayName()));
}
var properties = entityType.GetDeclaredProperties().ToDictionary(p => p.Name);
if (mappingStrategy == RelationalAnnotationNames.TphMappingStrategy)
{
if (entityType.BaseType != null)
{
return;
}
foreach (var property in entityType.GetDerivedProperties())
{
properties.Add(property.Name, property);
}
}
else if (mappingStrategy == RelationalAnnotationNames.TpcMappingStrategy)View on GitHub (pinned to dbf9771522)
Solutions
- Define a primary key on the entity (HasKey) so it can be identified for sproc operations.
- Or remove the stored procedure mapping and keep the entity as a query/view (read-only).
Example fix
// before
modelBuilder.Entity<BlogStat>().HasNoKey().InsertStoredProcedure("sp_InsertStat");
// after
modelBuilder.Entity<BlogStat>().HasKey(x => x.Id).InsertStoredProcedure("sp_InsertStat"); Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in modelBuilder.Model.GetEntityTypes())
{
if (et.FindPrimaryKey() == null && (et.GetInsertStoredProcedure() != null || et.GetUpdateStoredProcedure() != null || et.GetDeleteStoredProcedure() != null))
throw new InvalidOperationException($"Keyless {et.DisplayName()} cannot be mapped to sprocs");
} Try / catch
try { _ = ctx.Model; } catch (InvalidOperationException ex) when (ex.Message.Contains("requires a primary key")) { /* add a key or remove the sproc mapping */ } Prevention
- Never configure sprocs on HasNoKey entities.
- Keep keyless read models separate from writable, keyed entities.
When it happens
Trigger: Configuring Insert/Update/Delete sprocs on a query type or a HasNoKey() entity; converting a keyless view entity to sproc-based mapping.
Common situations: Treating a read-only/keyless projection as if it were writable; sproc config copied from a keyed entity onto a keyless one.
Related errors
- The entity type '{entityType}' was configured to use some st
- The entity type '{entityType}' was configured to use '{sproc
- The property '{entityType}.{property}' is mapped to an outpu
- The property '{entityType}.{property}' is mapped to a result
- The entity type '{entityType}' is mapped to the stored proce
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/30ec55e0d6c6c7ab.
Report an issue: GitHub.