{"record":{"id":"f7795bb35fae9de1","repo":"dotnet/efcore","slug":"a-rows-affected-parameter-result-column-or-return","errorCode":null,"errorMessage":"A rows affected parameter, result column or return value cannot be configured on stored procedure '{sproc}' because it is used for insertion. Rows affected values are only allowed on stored procedures performing updating or deletion.","messagePattern":"A rows affected parameter, result column or return value cannot be configured on stored procedure '(.+?)' because it is used for insertion\\. Rows affected values are only allowed on stored procedures performing updating or deletion\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":915,"sourceCode":"            }\n\n            if (properties.Count > 0)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.StoredProcedurePropertiesNotMapped(\n                        entityType.DisplayName(),\n                        storeObjectIdentifier.DisplayName(),\n                        properties.Values.Format()));\n            }\n        }\n\n        if (sproc.IsRowsAffectedReturned\n            || sproc.FindRowsAffectedParameter() != null\n            || sproc.FindRowsAffectedResultColumn() != null)\n        {\n            if (storeObjectIdentifier.StoreObjectType == StoreObjectType.InsertStoredProcedure)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.StoredProcedureRowsAffectedForInsert(\n                        storeObjectIdentifier.DisplayName()));\n            }\n\n            if (originalValueProperties.Values.FirstOrDefault(p => p.IsConcurrencyToken) is { } missedConcurrencyToken)\n            {\n                logger.StoredProcedureConcurrencyTokenNotMapped(entityType, missedConcurrencyToken, storeObjectIdentifier.DisplayName());\n            }\n\n            if (sproc.ResultColumns.Any(c => c != sproc.FindRowsAffectedResultColumn()))\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.StoredProcedureRowsAffectedWithResultColumns(\n                        entityType.DisplayName(),\n                        storeObjectIdentifier.DisplayName()));\n            }\n        }\n    }","sourceCodeStart":897,"sourceCodeEnd":933,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L897-L933","documentation":"Thrown when an INSERT stored procedure mapping is configured with a rows-affected return value: IsRowsAffectedReturned, a rows-affected parameter (FindRowsAffectedParameter), or a rows-affected result column (FindRowsAffectedResultColumn). Insert sprocs always insert exactly one row from EF's perspective, so a rows-affected value is meaningless and prohibited.","triggerScenarios":"Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:915 when the library encounters an invalid state.","commonSituations":"Copy-pasting an update sproc configuration to an insert sproc without removing the rows-affected call; switching a sproc from update to insert semantics; misreading docs and assuming rows-affected is universal.","solutions":["Remove the .RowsAffectedReturn() / .RowsAffectedParameter(...) / .RowsAffectedResultColumn(...) call from the InsertUsingStoredProcedure configuration.","Keep rows-affected configuration only on UpdateUsingStoredProcedure and DeleteUsingStoredProcedure."],"exampleFix":"// before\nentityType.InsertUsingStoredProcedure(\"InsertOrder\",\n    sp =>\n    {\n        sp.HasParameter(o => o.CustomerId);\n        sp.RowsAffectedReturn(); // illegal for insert\n    });\n\n// after\nentityType.InsertUsingStoredProcedure(\"InsertOrder\",\n    sp => sp.HasParameter(o => o.CustomerId));","handlingStrategy":"validation","validationCode":"foreach (var et in model.GetEntityTypes())\n{\n    var insert = et.GetInsertStoredProcedure();\n    if (insert == null) continue;\n    if (insert.IsRowsAffectedReturned\n        || insert.FindRowsAffectedParameter() != null\n        || insert.FindRowsAffectedResultColumn() != null)\n    {\n        Console.WriteLine($\"Insert sproc {insert.Name} must not configure rows-affected.\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep rows-affected configuration only on update/delete sprocs; never insert.","Write insert sproc configs from a blank builder, not by cloning an update config.","Code-review insert sproc mappings for rows-affected calls."],"tags":["ef-core","stored-procedures","model-validation","insert"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}