dotnet/efcore · error · InvalidOperationException
Entity type ' ' has a split mapping, but it doesn't map any…
Error message
Entity type '{entityType}' has a split mapping, but it doesn't map any non-primary key property to the main store object. Keep at least one non-primary key property mapped to a column on '{storeObject}'. What it means
ValidateMainMapping walks the MAIN store object (the entity's primary table/view). It requires at least one non-key property still mapped there (propertyFound). If every non-key property has been moved onto split fragments so the main object holds only the key, the mapping is rejected — entity splitting must leave payload on the main table.
Solutions
- Keep at least one non-key property mapped to the main store object (do not null-out all payload columns on the default table).
- Audit table-specific overrides on the default ToTable to confirm none of them strip every payload column.
- If the intent really is a key-only root, redesign with owned types or a separate entity instead of splitting.
Example fix
// before — every payload column unmapped on main table
modelBuilder.Entity<Invoice>()
.ToTable("Invoice", tb =>
{
tb.Property(i => i.Amount).HasColumnName(null);
tb.Property(i => i.Note).HasColumnName(null);
})
.SplitToTable("InvoiceDetail", tb =>
{
tb.Property(i => i.Id).HasColumnName("Id");
tb.Property(i => i.Amount).HasColumnName("Amount");
tb.Property(i => i.Note).HasColumnName("Note");
}); // main has only Id -> [442]
// after — keep a payload column on the main table
modelBuilder.Entity<Invoice>()
.ToTable("Invoice", tb => tb.Property(i => i.Amount).HasColumnName("Amount"))
.SplitToTable("InvoiceDetail", tb =>
{
tb.Property(i => i.Id).HasColumnName("Id");
tb.Property(i => i.Note).HasColumnName("Note");
}); Defensive patterns
Strategy: validation
Validate before calling
// Verify the main store object keeps at least one non-key property.
static bool MainHasPayload(IEntityType et, StoreObjectIdentifier main)
=> et.GetProperties().Any(p => !p.IsPrimaryKey() && p.GetColumnName(main) is not null); Prevention
- Do not unmapping every payload column off the default ToTable when using splitting.
- Audit table-specific overrides on the main table after refactoring.
- Add a unit test that builds the model and asserts main-table payload presence.
When it happens
Trigger: Splitting an entity and unmapping every non-PK property from the main table (e.g. .HasColumnName(null) on the default table for all payload properties while mapping them only to SplitToTable fragments), so propertyFound stays false inside ValidateMainMapping.
Common situations: Over-aggressive splitting; treating the main table as a pure key/join table; bugs in code-generated mapping where the main ToTable loses its columns.
Related errors
- Entity type ' ' has a split mapping for ' ', but it doesn't…
- Entity type ' ' has a split mapping for ' ', but the…
- Both entity type ' ' and ' ' were configured to use ' '…
- Current value parameter
- Entity type ' ' doesn't contain a property mapped to the…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/2d8098c2983dee60.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:2495
}
var columnName = property.GetColumnName(mainObject);
if (columnName != null)
{
propertyFound = true;
if (!nonSharedRequiredPropertyFound
&& !property.IsNullable
&& property.FindSharedStoreObjectRootProperty(mainObject) == null)
{
nonSharedRequiredPropertyFound = true;
}
}
}
if (!propertyFound)
{
throw new InvalidOperationException(
RelationalStrings.EntitySplittingMissingPropertiesMainFragment(
entityType.DisplayName(), mainObject.DisplayName()));
}
if (!nonSharedRequiredPropertyFound)
{
var rowInternalFk = entityType.FindRowInternalForeignKeys(mainObject).First(fk => !fk.IsRequiredDependent);
throw new InvalidOperationException(
RelationalStrings.EntitySplittingMissingRequiredPropertiesOptionalDependent(
entityType.DisplayName(), mainObject.DisplayName(),
$".Navigation(p => p.{rowInternalFk.PrincipalToDependent!.Name}).IsRequired()"));
}
return mainObject;
}
}
/// <summary>View on GitHub (pinned to 3a2006ef56)