dotnet/efcore · error · InvalidOperationException
The entity type ' ' is mapped to the stored procedure ' '…
Error message
The entity type '{entityType}' is mapped to the stored procedure '{sproc}', however the properties {properties} are not mapped to any parameter or result column. What it means
Thrown when, after sproc parameter processing, the `properties` set (entity properties that EF expects to send to the sproc) still has entries that are neither mappable as current-value parameters nor original-value parameters. Each remaining property must have been consumed by a HasParameter/HasOriginalValueParameter call; otherwise the model is incomplete and SaveChanges would silently skip writing data.
Solutions
- Add .HasParameter(p => p.TheProperty) (or HasOriginalValueParameter for concurrency tokens) to the relevant sproc mapping for every property listed in the error.
- If the property should not be persisted by this sproc (e.g. computed-only, never written), configure it so: .ValueGeneratedOnAddOrUpdate() and AfterSaveBehavior.Ignore / BeforeSaveBehavior.Ignore as appropriate so the validator removes it from the expected set.
- Verify IsRequired/IsRequiredWhenSaved semantics — a property declared on the entity but unassigned by the user may still be required by the sproc mapping.
Example fix
// before
entityType.UpdateUsingStoredProcedure("UpdateOrder",
sp =>
{
sp.HasParameter(o => o.OrderId);
// forgot Status -> listed as unmapped
});
// after
entityType.UpdateUsingStoredProcedure("UpdateOrder",
sp =>
{
sp.HasParameter(o => o.OrderId);
sp.HasParameter(o => o.Status);
}); Defensive patterns
Strategy: validation
Validate before calling
// After building the model, log any property EF considers unmapped for the sproc.
foreach (var et in model.GetEntityTypes())
{
foreach (var sproc in new[] { et.GetInsertStoredProcedure(), et.GetUpdateStoredProcedure(), et.GetDeleteStoredProcedure() })
{
if (sproc == null) continue;
var mapped = sproc.Parameters.Select(p => p.PropertyName).Where(n => n != null).ToHashSet();
foreach (var prop in et.GetProperties())
{
if (!mapped.Contains(prop.Name)
&& (et.GetTableName() != null || prop.IsPrimaryKey() || prop.IsConcurrencyToken))
{
// Heuristic: only flag properties the validator would expect.
Console.WriteLine($"{et.Name}.{prop.Name} not present on {sproc.Name}.");
}
}
}
} Prevention
- When you add a new property to an entity, audit every sproc mapping (insert/update/delete) for that entity.
- Centralize sproc mapping per entity in one file so omissions are visible.
- Keep an integration test that asserts the model finalizes without throwing.
When it happens
Trigger: An entity has properties that the validator cannot reconcile with any sproc parameter, result column, or original-value slot. Specifically: on Update sproc, a property that is a non-key, non-concurrency-token, non-OnUpdate-generated, non-Save-after-save-behavior property but is still expected to be persisted; on Insert sproc, a non-OnAdd, non-Save-before-save-behavior property; or any property the developer expects the sproc to handle but did not map.
Common situations: Adding a new property to the entity and forgetting to add the sproc parameter; mapping only some columns of a table to the sproc; mixing TPH inheritance where derived properties are not surfaced in the sproc.
Related errors
- A rows affected parameter, result column or return value…
- Both ' ' and ' ' are explicitly mapped to the stored…
- Both ' ' and ' ' are mapped to the stored procedure ' '…
- ' ' is mapped to the stored procedure ' ' while ' ' is…
- Input parameter ' ' of update stored procedure ' ' is…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/99820eedac8d12d2.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:901
{
properties.Remove(property.Name);
}
break;
}
}
foreach (var property in properties.Keys.ToList())
{
if (!originalValueProperties.ContainsKey(property))
{
properties.Remove(property);
}
}
if (properties.Count > 0)
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedurePropertiesNotMapped(
entityType.DisplayName(),
storeObjectIdentifier.DisplayName(),
properties.Values.Format()));
}
}
if (sproc.IsRowsAffectedReturned
|| sproc.FindRowsAffectedParameter() != null
|| sproc.FindRowsAffectedResultColumn() != null)
{
if (storeObjectIdentifier.StoreObjectType == StoreObjectType.InsertStoredProcedure)
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureRowsAffectedForInsert(
storeObjectIdentifier.DisplayName()));
}
View on GitHub (pinned to 3a2006ef56)