dotnet/efcore · error · InvalidOperationException
Table name must be specified to configure a table-specific…
Error message
Table name must be specified to configure a table-specific property mapping.
What it means
OwnedNavigationTableBuilder.GetStoreObjectIdentifier() returns the builder's StoreObject; if it is null it throws MappingFragmentMissingName. Table-specific property configuration (Property(...)) needs a concrete named table to bind a column override to, so calling it on a builder that has no table name is invalid.
Solutions
- Specify a table name first: .ToTable("Address") (or .ToTable("Address", schema)) so the builder carries a StoreObjectIdentifier.
- If you do not need table-specific overrides, use the non-table-specific property configuration on the owned navigation builder directly.
- Confirm the OwnedNavigationTableBuilder you are using was produced from a named ToTable call.
Example fix
// before — table builder with no name
modelBuilder.Entity<Customer>()
.OwnsOne(c => c.Address, a =>
{
a.ToTable(tb => tb.Property("Line1").HasColumnName("AddrLine1")); // no table name -> [454]
});
// after — give the table a name
modelBuilder.Entity<Customer>()
.OwnsOne(c => c.Address, a =>
{
a.ToTable("CustomerAddress", tb => tb.Property(a => a.Line1).HasColumnName("AddrLine1"));
}); Defensive patterns
Strategy: validation
Validate before calling
// Ensure a table name is supplied before using table-specific property config.
if (string.IsNullOrEmpty(tableName))
throw new InvalidOperationException("A table name is required for table-specific property mapping."); Prevention
- Always call .ToTable(name, ...) before configuring table-specific columns.
- If you do not need table-specific overrides, configure the property on the entity builder directly.
- Review builder chaining to confirm the OwnedNavigationTableBuilder came from a named ToTable.
When it happens
Trigger: Invoking .Property("X") (or another table-specific method) on an OwnedNavigationTableBuilder whose StoreObject is null — e.g. the builder was obtained without a named table (a default/empty table builder) and you tried to configure a column mapping on it.
Common situations: Calling table-specific property config off an OwnedNavigationTableBuilder created for a default mapping; misusing a builder returned before .ToTable(name) was applied; chaining APIs incorrectly.
Related errors
- Table name must be specified to configure a table-specific…
- The property ' . ' could not be found. Ensure that the…
- The property ' . ' could not be found. Ensure that the…
- Entity type ' ' has a split mapping and is an optional…
- Entity type ' ' has a split mapping for ' ' that is shared…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/0b376604087c3ee3.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Metadata/Builders/OwnedNavigationTableBuilder.cs:164
/// <summary>
/// Maps the property to a column on the current table and returns an object that can be used
/// to provide table-specific configuration if the property is mapped to more than one table.
/// </summary>
/// <typeparam name="TProperty">The type of the property to be configured.</typeparam>
/// <param name="propertyName">The name of the property to be configured.</param>
/// <returns>An object that can be used to configure the property.</returns>
public virtual ColumnBuilder<TProperty> Property<TProperty>(string propertyName)
=> new(GetStoreObjectIdentifier(), OwnedNavigationBuilder.Property<TProperty>(propertyName));
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
[EntityFrameworkInternal]
protected virtual StoreObjectIdentifier GetStoreObjectIdentifier()
=> StoreObject ?? throw new InvalidOperationException(RelationalStrings.MappingFragmentMissingName);
OwnedNavigationBuilder IInfrastructure<OwnedNavigationBuilder>.Instance
=> OwnedNavigationBuilder;
#region Hidden System.Object members
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>A string that represents the current object.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string? ToString()
=> base.ToString();
/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
/// <param name="obj">The object to compare with the current object.</param>View on GitHub (pinned to 3a2006ef56)