dotnet/efcore · error · InvalidOperationException
The property ' . ' is mapped to a result column of the…
Error message
The property '{entityType}.{property}' is mapped to a result column of the stored procedure '{sproc}', but it is also mapped to an output parameter. A store-generated property can only be mapped to one of these. What it means
Thrown when a property is mapped to BOTH a result column and an output parameter of the same insert/update sproc (validator walks sproc.ResultColumns and tries to remove each result-column property from storeGeneratedProperties; if it was already consumed by an output parameter earlier, the set removal fails). A store-generated property may be read back through only one channel — result column OR output parameter, not both.
Solutions
- Choose one read-back mechanism: drop .HasOutputParameter(p => p.Foo) and keep .HasResultColumn(p => p.Foo), or vice versa.
- If the sproc genuinely returns both, split the property into two mapped properties — but that is rarely correct; instead align the sproc to return the value once.
Example fix
// before
entityType.InsertUsingStoredProcedure("InsertOrder",
sp =>
{
sp.HasOutputParameter(o => o.OrderId);
sp.HasResultColumn(o => o.OrderId); // duplicate read-back
});
// after
entityType.InsertUsingStoredProcedure("InsertOrder",
sp => sp.HasResultColumn(o => o.OrderId)); Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in model.GetEntityTypes())
{
foreach (var sproc in new[] { et.GetInsertStoredProcedure(), et.GetUpdateStoredProcedure() })
{
if (sproc == null) continue;
var outputProps = sproc.Parameters
.Where(p => p.Direction != System.Data.ParameterDirection.Input && p.PropertyName != null)
.Select(p => p.PropertyName)
.ToHashSet();
foreach (var rc in sproc.ResultColumns.Where(c => c.PropertyName != null))
{
if (outputProps.Contains(rc.PropertyName))
Console.WriteLine($"{et.Name}.{rc.PropertyName} on {sproc.Name} is both an output parameter and a result column.");
}
}
} Prevention
- Decide per sproc whether to use output parameters OR result columns, then enforce it in code review.
- When migrating between the two, search-and-remove the old mapping before adding the new one.
- Document the chosen convention for each entity type.
When it happens
Trigger: On Insert/UpdateUsingStoredProcedure: .HasOutputParameter(p => p.Id) plus .HasResultColumn(p => p.Id) for the same property. Common when migrating from output parameters to result-set based sprocs without removing the old mapping.
Common situations: Switching a sproc from OUT parameter to SELECT-based return and leaving both calls in the fluent config; copy-paste of insert config to update config where one used OutputParameter and the other ResultColumn.
Related errors
- The entity type ' ' is mapped to the stored procedure ' '…
- The property ' . ' is mapped to an output parameter of the…
- The property ' . ' is mapped to an output parameter of the…
- A rows affected parameter, result column or return value…
- Both ' ' and ' ' are explicitly mapped to the stored…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/eabc9557fa89c01f.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:841
break;
default:
Check.DebugFail("Unexpected stored procedure type: " + storeObjectIdentifier.StoreObjectType);
break;
}
}
foreach (var resultColumn in sproc.ResultColumns)
{
if (resultColumn.PropertyName == null)
{
continue;
}
properties.Remove(resultColumn.PropertyName);
if (!storeGeneratedProperties.Remove(resultColumn.PropertyName))
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureResultColumnParameterConflict(
entityType.DisplayName(), resultColumn.PropertyName, storeObjectIdentifier.DisplayName()));
}
}
if (storeGeneratedProperties.Count > 0)
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureGeneratedPropertiesNotMapped(
entityType.DisplayName(),
storeObjectIdentifier.DisplayName(),
storeGeneratedProperties.Values.Format()));
}
if (properties.Count > 0)
{
foreach (var property in properties.Values.ToList())
{View on GitHub (pinned to 3a2006ef56)