dotnet/efcore · error · InvalidOperationException

The result column ' ' cannot be added to the stored…

Error message

The result column '{column}' cannot be added to the stored procedure '{sproc}' because another result column with this name already exists.

What it means

Thrown in the same result-column loop when two result columns share the same store Name (RelationalModelValidator.cs:664-669). A HashSet<string> resultColumnNames tracks seen names; Add returns false on a duplicate. Result columns must have unique store names so EF can disambiguate values returned by the sproc.

Solutions

  1. Give each result column a distinct store name: sp.HasResultColumn(x => x.Foo).HasColumnName("foo_col") and ensure no two share it.
  2. Remove the duplicate HasResultColumn call.
  3. If the DB result set truly has duplicates, alias them in the sproc so each column name is unique.

Example fix

// before
sp.HasResultColumn(x => x.RowVersion).HasColumnName("ts");
sp.HasResultColumn(x => x.Timestamp).HasColumnName("ts"); // duplicate store name

// after
sp.HasResultColumn(x => x.RowVersion).HasColumnName("row_version");
sp.HasResultColumn(x => x.Timestamp).HasColumnName("row_ts");
Defensive patterns

Strategy: validation

Validate before calling

foreach (var et in modelBuilder.Model.GetEntityTypes())
{
    foreach (var sproc in new[] { et.GetInsertStoredProcedure(), et.GetUpdateStoredProcedure(), et.GetDeleteStoredProcedure() })
    {
        if (sproc is null) continue;
        var names = sproc.ResultColumns.Select(rc => rc.Name).ToList();
        if (names.Count != names.Distinct().Count())
            throw new InvalidOperationException($"Duplicate result-column store names on sproc '{sproc.GetStoreIdentifier().DisplayName}': {string.Join(", ", names)}.");
    }
}

Try / catch

try { _ = ctx.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("another result column with this name already exists"))
{
    logger.LogError("Duplicate result-column name on sproc. {Msg}", ex.Message);
    throw;
}

Prevention

When it happens

Trigger: Configuring two result columns that map to the same store column name (e.g., both defaulting to 'Id', or explicitly set HasResultColumn(...).HasName("Id") twice). Often from copy-paste or from a property rename where both bindings fell back to the same column.

Common situations: Two properties both named with column 'Id' after a refactor; scaffolding a sproc whose result set has duplicate aliases; an owned/complex property whose column collided with the owner's.

Related errors


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

Appendix: source

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

                storeGeneratedProperties.Remove(property.Name);
            }
        }

        var resultColumnNames = new HashSet<string>();
        foreach (var resultColumn in sproc.ResultColumns)
        {
            IProperty? property = null!;
            if (resultColumn.PropertyName != null
                && !properties.TryGetValue(resultColumn.PropertyName, out property))
            {
                throw new InvalidOperationException(
                    RelationalStrings.StoredProcedureResultColumnNotFound(
                        resultColumn.PropertyName, entityType.DisplayName(), storeObjectIdentifier.DisplayName()));
            }

            if (!resultColumnNames.Add(resultColumn.Name))
            {
                throw new InvalidOperationException(
                    RelationalStrings.StoredProcedureDuplicateResultColumnName(
                        resultColumn.Name, storeObjectIdentifier.DisplayName()));
            }

            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()));

View on GitHub (pinned to 3a2006ef56)