dotnet/efcore · error · InvalidOperationException

Entity type '{entityType}' has a split mapping for '{storeOb

Error message

Entity type '{entityType}' has a split mapping for '{storeObject}', but is it also mapped to the same object. Split mappings should not duplicate the main mapping.

What it means

A split fragment's StoreObjectIdentifier must NOT equal the entity's main mapping store object for the same type; splitting is for ADDITIONAL store objects beyond the main one. ValidateMappingFragment throws when fragment.StoreObject == mainStoreObject, i.e. you told EF to split a table into itself.

Source

Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:2396

            throw new InvalidOperationException(
                RelationalStrings.EntitySplittingHierarchy(entityType.DisplayName(), fragments.First().StoreObject.DisplayName()));
        }

        var anyTableFragments = false;
        var anyViewFragments = false;
        foreach (var fragment in fragments)
        {
            var mainStoreObject = StoreObjectIdentifier.Create(entityType, fragment.StoreObject.StoreObjectType);
            if (mainStoreObject == null)
            {
                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()));
                }
            }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Rename the split fragment's table to a different physical table: .SplitToTable("CustomerExtras", ...).
  2. Remove the redundant fragment that duplicates the main mapping.
  3. If you intended to move all properties to one table, drop splitting entirely and use the main ToTable.

Example fix

// before
modelBuilder.Entity<Customer>().ToTable("Customers")
    .SplitToTable("Customers", t => t.Property(c => c.Notes)); // same as main

// after
modelBuilder.Entity<Customer>().ToTable("Customers")
    .SplitToTable("CustomerExtras", t => t.Property(c => c.Notes));
Defensive patterns

Strategy: validation

Validate before calling

bool SplitFragmentsDifferFromMain(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;
            if (f.StoreObject == main) return false;
        }
    }
    return true;
}

Try / catch

try { _ = context.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("split mapping", StringComparison.Ordinal) && ex.Message.Contains("duplicate the main mapping", StringComparison.Ordinal))
{
    throw new InvalidOperationException("A split fragment must not reuse the entity's main table. Rename the fragment table or remove it.", ex);
}

Prevention

When it happens

Trigger: Calling .SplitToTable("Customers", ...) on an entity whose main table is ALSO "Customers" (same name and schema), so the fragment store object equals the main. The equality check fragment.StoreObject == mainStoreObject fails.

Common situations: Copy-pasting the main table name into a SplitToTable call; scaffolding splits and forgetting to rename; refactoring that left a fragment pointing back at the primary table.

Related errors


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