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 store-generated values are not supported for Delete stored procedures.

What it means

Thrown in the result-column switch when storeObjectIdentifier.StoreObjectType is DeleteStoredProcedure (RelationalModelValidator.cs:688-691). Delete sprocs should not return values; nothing is store-generated on delete. Any HasResultColumn on a delete sproc triggers this — there is no valid scenario.

Solutions

  1. Remove all HasResultColumn(...) calls from the delete-stored-procedure configuration.
  2. If the DB sproc returns a rowcount or status, ignore it client-side — do not map it as a result column.
  3. Use OutputParameter(...) if you need a scalar return value from the delete sproc.

Example fix

// before
modelBuilder.Entity<Customer>()
    .DeleteUsingStoredProcedure("dbo.CustomerDelete", sp =>
    {
        sp.HasOriginalValueParameter(c => c.Id);
        sp.HasResultColumn(c => c.Id); // throws — delete sproc has no result
    });

// after
modelBuilder.Entity<Customer>()
    .DeleteUsingStoredProcedure("dbo.CustomerDelete", sp =>
    {
        sp.HasOriginalValueParameter(c => c.Id);
    });
Defensive patterns

Strategy: validation

Validate before calling

foreach (var et in modelBuilder.Model.GetEntityTypes())
{
    var delete = et.GetDeleteStoredProcedure();
    if (delete is not null && delete.ResultColumns.Count > 0)
        throw new InvalidOperationException($"Delete sproc '{delete.GetStoreIdentifier().DisplayName}' on '{et.Name}' must not have result columns.");
}

Try / catch

try { _ = ctx.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("not supported for Delete stored procedures"))
{
    logger.LogError("Remove all HasResultColumn calls from the delete sproc. {Msg}", ex.Message);
    throw;
}

Prevention

When it happens

Trigger: Configuring .DeleteUsingStoredProcedure(... sp => sp.HasResultColumn(x => x.Something)). Even one result column on a delete sproc throws unconditionally.

Common situations: Copy-pasting an insert sproc block to a delete sproc and forgetting to strip result columns; misunderstanding that delete sprocs don't return affected rows back into entities.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/7d2738fd52261036. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:689

            if (resultColumn.PropertyName == null)
            {
                continue;
            }

            switch (storeObjectIdentifier.StoreObjectType)
            {
                case StoreObjectType.InsertStoredProcedure:
                case StoreObjectType.UpdateStoredProcedure:
                    if (!storeGeneratedProperties.ContainsKey(property.Name))
                    {
                        throw new InvalidOperationException(
                            RelationalStrings.StoredProcedureResultColumnNotGenerated(
                                entityType.DisplayName(), resultColumn.PropertyName, storeObjectIdentifier.DisplayName()));
                    }

                    break;
                case StoreObjectType.DeleteStoredProcedure:
                    throw new InvalidOperationException(
                        RelationalStrings.StoredProcedureResultColumnDelete(
                            entityType.DisplayName(), resultColumn.PropertyName, storeObjectIdentifier.DisplayName()));
                default:
                    Check.DebugFail("Unexpected stored procedure type: " + storeObjectIdentifier.StoreObjectType);
                    break;
            }
        }

        var originalValueProperties = new Dictionary<string, IProperty>(properties);
        var parameterNames = new HashSet<string>();
        foreach (var parameter in sproc.Parameters)
        {
            IProperty? property = null;
            if (parameter.PropertyName != null)
            {
                if (parameter.ForOriginalValue == true)
                {
                    if (!originalValueProperties.TryGetAndRemove(parameter.PropertyName, out property))

View on GitHub (pinned to 3a2006ef56)