dotnet/efcore · error · InvalidOperationException
The entity type ' ' was configured to use ' ', but the…
Error message
The entity type '{entityType}' was configured to use '{sproc}', but the store name was not specified. Configure the stored procedure name explicitly. What it means
Thrown inside the local ValidateStoredProcedureName function when StoreObjectIdentifier.Create(entityType, storedProcedureType) returns null — meaning the stored procedure's store name cannot be derived (RelationalModelValidator.cs:516-522). This happens when the sproc is configured but no name/schema was supplied and no convention could fill it.
Solutions
- Supply the stored-procedure name explicitly: .InsertUsingStoredProcedure("dbo.CustomerInsert", sp => { ... }) (and likewise for Update/Delete).
- If using the overload that takes a builder without a name, add .HasName("YourSproc") inside the configuration.
- Ensure conventions that compute default names are enabled (haven't been removed via modelBuilder.Model.RemoveConvention(...)).
- Verify the entity itself has a name (entityType.DisplayName()) so the convention has something to base the sproc name on.
Example fix
// before — name omitted, convention yields nothing
modelBuilder.Entity<Customer>()
.InsertUsingStoredProcedure(sp =>
{
sp.HasParameter(c => c.Id);
sp.HasResultColumn(c => c.Id);
});
// after — explicit store name and schema
modelBuilder.Entity<Customer>()
.InsertUsingStoredProcedure("dbo.CustomerInsert", sp =>
{
sp.HasParameter(c => c.Id);
sp.HasResultColumn(c => c.Id);
}); Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in modelBuilder.Model.GetEntityTypes())
{
foreach (StoreObjectType kind in new[] { StoreObjectType.InsertStoredProcedure, StoreObjectType.UpdateStoredProcedure, StoreObjectType.DeleteStoredProcedure })
{
if (StoreObjectIdentifier.Create(et, kind) is null
&& (kind == StoreObjectType.InsertStoredProcedure ? et.GetInsertStoredProcedure()
: kind == StoreObjectType.UpdateStoredProcedure ? et.GetUpdateStoredProcedure()
: et.GetDeleteStoredProcedure()) is not null)
{
throw new InvalidOperationException($"Entity '{et.Name}' has a {kind} with no store name; call .HasName(...).");
}
}
} Try / catch
try { _ = ctx.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("store name was not specified"))
{
logger.LogError("Supply an explicit sproc name. {Msg}", ex.Message);
throw;
} Prevention
- Always pass an explicit name string to *UsingStoredProcedure(...).
- Avoid disabling naming conventions that compute default sproc names.
- In IEntityTypeConfiguration, set .HasName(...) inside every sproc builder.
When it happens
Trigger: Calling .InsertUsingStoredProcedure(sp => { }) with an empty/null name or relying on convention-based name resolution when conventions are disabled or the entity name is unset. Also when a custom IModelCustomizer strips the name annotation.
Common situations: Using the lambda overload that omits the explicit name and the default-name convention produced an empty string; setting HasName(null); scaffolding generated incomplete sproc config; running with model caching where the name was conditionally set and the cache key didn't differentiate.
Related errors
- Both entity type ' ' and ' ' were configured to use ' '…
- The entity type ' ' was configured to use some stored…
- The keyless entity type
- Current value parameter
- Input parameter ' ' of insert stored procedure ' ' is…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/16eae5e3c083182f.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:519
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.
/// </summary>
/// <param name="mappedTypes">The entity types mapped to the stored procedure.</param>
/// <param name="storedProcedure">The stored procedure identifier.</param>
/// <param name="logger">The logger to use.</param>
protected virtual void ValidateStoredProcedure(
IReadOnlyList<IEntityType> mappedTypes,
in StoreObjectIdentifier storedProcedure,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
=> ValidateStoredProcedureCompatibility(mappedTypes, storedProcedure, logger);
View on GitHub (pinned to 3a2006ef56)