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

  1. Map the dependent's split fragments to non-shared (independent) tables so they do not rely on the principal's table.
  2. Realign the dependent's main mapping onto the principal's store object (principalMainFragment) so main and split agree.
  3. 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 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


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