dotnet/efcore · error · InvalidOperationException
The rows affected result column cannot be added to the…
Error message
The rows affected result column cannot be added to the stored procedure '{sproc}' because the rows affected are already returned via another column, via a parameter or via the stored procedure return value. What it means
The rows-affected count may be returned through only one channel. AddRowsAffectedResultColumn() throws when rows affected is already carried by an existing result column, a parameter, or the stored procedure's return value. This mirrors AddRowsAffectedParameter() but guards the result-column channel.
Solutions
- Check FindRowsAffectedResultColumn(), FindRowsAffectedParameter(), and IsRowsAffectedReturned before adding a result column.
- Pick exactly one rows-affected channel and remove the others.
- If the procedure SELECTs rows affected, use .RowsAffectedResultColumn() alone.
- Rebuild the procedure mapping from scratch if the source of the duplicate channel is unclear.
Example fix
// before sp.RowsAffectedParameter(); sp.RowsAffectedResultColumn(); // throws // after sp.RowsAffectedResultColumn();
Defensive patterns
Strategy: validation
Validate before calling
var sp = entityType.GetUpdateStoredProcedure();
if (sp is not null
&& sp.FindRowsAffectedResultColumn() is null
&& sp.FindRowsAffectedParameter() is null
&& !sp.IsRowsAffectedReturned)
{
sp.RowsAffectedResultColumn();
} Type guard
static bool CanAddRowsAffectedResultColumn(IStoredProcedure sp)
=> sp.FindRowsAffectedResultColumn() is null
&& sp.FindRowsAffectedParameter() is null
&& !sp.IsRowsAffectedReturned; Prevention
- Pick one rows-affected channel per procedure and never mix.
- Encapsulate the choice in a shared helper invoked for Insert/Update/Delete.
- Validate the model in tests to catch duplicate channels before runtime.
When it happens
Trigger: Calling .RowsAffectedResultColumn() after .RowsAffectedParameter(), .RowsAffectedResultColumn(), or .RowsAffectedReturned() was already applied to the same stored procedure.
Common situations: Switching a procedure's rows-affected mechanism (e.g. from an output parameter to a SELECT result set) without removing the prior configuration; copy-pasting fluent blocks across Insert/Update/Delete mappings; conventions from a prior EF version leaving a residual channel after an upgrade.
Related errors
- The rows affected parameter cannot be added to the stored…
- ' ' cannot be configured for the parameter ' ' of the…
- The result column for the property
- The entity type ' ' was not found. Ensure that the entity…
- The stored procedure
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/80e1b14931572b71.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs:653
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual StoredProcedureResultColumn? FindRowsAffectedResultColumn()
=> _rowsAffectedResultColumn;
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual StoredProcedureResultColumn AddRowsAffectedResultColumn()
{
if (_rowsAffectedResultColumn != null
|| _rowsAffectedParameter != null
|| _isRowsAffectedReturned)
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureDuplicateRowsAffectedResultColumn(
((IReadOnlyStoredProcedure)this).GetStoreIdentifier()?.DisplayName()));
}
var resultColumn = new StoredProcedureResultColumn(this, forRowsAffected: true, propertyName: null);
_resultColumns.Add(resultColumn);
_rowsAffectedResultColumn = resultColumn;
return resultColumn;
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public override string ToString()View on GitHub (pinned to 3a2006ef56)