dotnet/efcore · error · InvalidOperationException

The entity type '{entityType}' was configured to use some st

Error message

The entity type '{entityType}' was configured to use some stored procedures and is not mapped to any table. An entity type that isn't mapped to a table must be mapped to insert, update and delete stored procedures.

What it means

Thrown when an entity type has some stored procedures configured but is not mapped to any table (GetTableName() == null). Entity types that skip table mapping must be fully covered by insert, update AND delete stored procedures; a partial sproc set with no table is invalid. The validator counts configured sprocs and rejects a non-zero count with a null table name.

Source

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

            ValidateStoredProcedureName(StoreObjectType.InsertStoredProcedure, entityType);
            ValidateSproc(insertStoredProcedure, mappingStrategy, logger);
            sprocCount++;
        }

        var updateStoredProcedure = entityType.GetUpdateStoredProcedure();
        if (updateStoredProcedure != null)
        {
            ValidateStoredProcedureName(StoreObjectType.UpdateStoredProcedure, entityType);
            ValidateSproc(updateStoredProcedure, mappingStrategy, logger);
            sprocCount++;
        }

        if (sprocCount > 0
            // TODO: Support this with #28703
            //&& sprocCount < 3
            && entityType.GetTableName() == null)
        {
            throw new InvalidOperationException(RelationalStrings.StoredProcedureUnmapped(entityType.DisplayName()));
        }

        static void ValidateStoredProcedureName(
            StoreObjectType storedProcedureType,
            IEntityType entityType)
        {
            var sprocId = StoreObjectIdentifier.Create(entityType, storedProcedureType);
            if (sprocId == null)
            {
                throw new InvalidOperationException(
                    RelationalStrings.StoredProcedureNoName(
                        entityType.DisplayName(), storedProcedureType));
            }
        }
    }

    /// <summary>
    ///     Validates a single stored procedure and all entity types mapped to it.

View on GitHub (pinned to dbf9771522)

Solutions

  1. Add all three stored procedures: InsertStoredProcedure, UpdateStoredProcedure, and DeleteStoredProcedure.
  2. Or restore a table mapping (ToTable/ToView) so the entity is not unmapped.

Example fix

// before
modelBuilder.Entity<Blog>()
    .ToView(null)
    .InsertStoredProcedure("sp_InsertBlog");

// after
modelBuilder.Entity<Blog>()
    .InsertStoredProcedure("sp_InsertBlog")
    .UpdateStoredProcedure("sp_UpdateBlog")
    .DeleteStoredProcedure("sp_DeleteBlog");
Defensive patterns

Strategy: validation

Validate before calling

foreach (var et in modelBuilder.Model.GetEntityTypes())
{
    var hasSproc = et.GetInsertStoredProcedure() != null || et.GetUpdateStoredProcedure() != null || et.GetDeleteStoredProcedure() != null;
    if (hasSproc && et.GetTableName() == null)
    {
        var count = (et.GetInsertStoredProcedure() != null ? 1 : 0) + (et.GetUpdateStoredProcedure() != null ? 1 : 0) + (et.GetDeleteStoredProcedure() != null ? 1 : 0);
        if (count < 3) throw new InvalidOperationException($"{et.DisplayName()} has partial sprocs and no table");
    }
}

Try / catch

try { _ = ctx.Model; } catch (InvalidOperationException ex) when (ex.Message.Contains("not mapped to any table")) { /* add the missing update/delete sprocs or a table mapping */ }

Prevention

When it happens

Trigger: Calling .InsertStoredProcedure(...) on an entity with ToView/HasNoKey/no ToTable, without also adding Update and Delete sprocs; migrating an entity off tables onto sprocs but only finishing the insert.

Common situations: Switching a keyless or view-backed entity to sprocs piecemeal; partial config left over from a refactor.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/c4207d6f083ff6d6. Report an issue: GitHub.