dotnet/efcore · error · InvalidOperationException
Entity type '{entityType}' has a split mapping for '{storeOb
Error message
Entity type '{entityType}' has a split mapping for '{storeObject}' that is shared with the entity type '{principalEntityType}', but the main mappings of these types do not share a table. Map the split fragments of '{entityType}' to non-shared tables or map the main fragment to '{principalStoreObject}'. What it means
When a split fragment is shared with a principal entity via a row-internal foreign key, ValidateMappingFragment checks that the MAIN mappings of the dependent and principal share the same table. If principalMainFragment != mainStoreObject (the dependent's main table), the split is inconsistent with how the entities are otherwise mapped, and EF throws.
Source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:2407
throw new InvalidOperationException(
RelationalStrings.EntitySplittingUnmappedMainFragment(
entityType.DisplayName(), fragment.StoreObject.DisplayName(), fragment.StoreObject.StoreObjectType));
}
if (fragment.StoreObject == mainStoreObject)
{
throw new InvalidOperationException(
RelationalStrings.EntitySplittingConflictingMainFragment(
entityType.DisplayName(), fragment.StoreObject.DisplayName()));
}
foreach (var foreignKey in entityType.FindRowInternalForeignKeys(fragment.StoreObject))
{
var principalMainFragment = StoreObjectIdentifier.Create(
foreignKey.PrincipalEntityType, fragment.StoreObject.StoreObjectType)!.Value;
if (principalMainFragment != mainStoreObject)
{
throw new InvalidOperationException(
RelationalStrings.EntitySplittingUnmatchedMainTableSplitting(
entityType.DisplayName(),
fragment.StoreObject.DisplayName(),
foreignKey.PrincipalEntityType.DisplayName(),
principalMainFragment.DisplayName()));
}
}
var propertiesFound = false;
foreach (var property in entityType.GetProperties())
{
var columnName = property.GetColumnName(fragment.StoreObject);
if (columnName == null)
{
if (property.IsPrimaryKey())
{
throw new InvalidOperationException(
RelationalStrings.EntitySplittingMissingPrimaryKey(View on GitHub (pinned to dbf9771522)
Solutions
- Map the dependent's split fragments to non-shared (independent) tables so they do not rely on the principal's table.
- Realign the dependent's main mapping onto the principal's store object (principalMainFragment) so main and split agree.
- Remove the row-internal FK / shared-table relationship that introduced the inconsistency.
Example fix
// before
modelBuilder.Entity<Order>().ToTable("Orders");
modelBuilder.Entity<Order>().OwnsOne(o => o.Detail, d => d.ToTable("Orders")); // detail main shared
modelBuilder.Entity<Order>().SplitToTable("OrderExtras", t => t.Property(...));
// principal main ('Orders') != dependent main when split expects shared
// after (align main fragment to principal table)
modelBuilder.Entity<Order>().OwnsOne(o => o.Detail, d => d.ToTable("Orders"));
modelBuilder.Entity<Order>().ToTable("Orders"); // main matches the shared principal table Defensive patterns
Strategy: validation
Validate before calling
bool SplitFragmentsAlignWithPrincipalMain(DbContext context)
{
foreach (var et in context.Model.GetEntityTypes())
foreach (var f in et.GetTableMappingFragments())
{
var main = StoreObjectIdentifier.Create(et, StoreObjectType.Table);
if (main is null) continue;
foreach (var fk in et.FindRowInternalForeignKeys(f.StoreObject))
{
var principalMain = StoreObjectIdentifier.Create(fk.PrincipalEntityType, StoreObjectType.Table);
if (principalMain is not null && principalMain != main) return false;
}
}
return true;
} Try / catch
try { _ = context.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("split mapping", StringComparison.Ordinal) && ex.Message.Contains("do not share a table", StringComparison.Ordinal))
{
throw new InvalidOperationException("A split fragment shares a principal's table but main mappings differ. Align the dependent's main table with the principal's, or move the fragment off the shared table.", ex);
} Prevention
- When table-splitting, keep the dependent's main table equal to the principal's main table.
- Avoid pointing split fragments at a principal's table unless main mappings also match.
- Test the model build after introducing shared-table relationships.
When it happens
Trigger: An entity has a split fragment, and on that fragment there is a row-internal FK whose principal's main store object (same StoreObjectType) differs from the dependent's main store object. Happens when a split fragment reuses a principal's table but the dependent's main table is something else.
Common situations: Table splitting where the dependent's extra fragment points at the principal's table while the dependent's own main table is unrelated; refactoring shared tables without updating both main and split mappings.
Related errors
- The entity type '{ownerType}' is not mapped, so by default t
- The entity type '{dependentType}' is mapped to '{storeObject
- The entity type '{dependentType}' is mapped to '{storeObject
- Entity type '{entityType}' has a split mapping for '{storeOb
- Entity type '{entityType}' has a split mapping for '{storeOb
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/0655c094be404b1c.
Report an issue: GitHub.