dotnet/efcore · error · InvalidOperationException

Entity type ' ' has a split mapping for ' ', but it doesn't…

Error message

Entity type '{entityType}' has a split mapping for '{storeObject}', but it doesn't have a main mapping of the same type. Map '{entityType}' to '{storeObjectType}'.

What it means

Thrown in the entity-splitting validator when a split mapping fragment exists for a given store-object type (table or view) but the entity has no main mapping of that same type — StoreObjectIdentifier.Create(entityType, fragment.StoreObject.StoreObjectType) returns null. A split fragment can only reference a store object that is the same kind as the entity's main mapping.

Solutions

  1. Add the main mapping of the same kind: ToTable("Customers") before SplitToTable("CustomerExtras").
  2. If splitting into views, ensure the entity also has a main ToView mapping.
  3. Remove the split fragment if no main mapping of that kind is intended.

Example fix

// before (split table with no main table)
modelBuilder.Entity<Customer>().SplitToTable("CustomerExtras", t =>
    t.Property(c => c.Notes)); // entity has no ToTable -> throws 437

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

Strategy: validation

Validate before calling

foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
    var fragments = EntityTypeMappingFragment.Get(entityType);
    if (fragments == null) continue;
    foreach (var fragment in fragments)
    {
        var main = StoreObjectIdentifier.Create(entityType, fragment.StoreObject.StoreObjectType);
        if (main == null)
            throw new InvalidOperationException($"{entityType.DisplayName()} has a split fragment for {fragment.StoreObject.DisplayName()} but no main {fragment.StoreObject.StoreObjectType} mapping.");
    }
}

Prevention

When it happens

Trigger: Configuring SplitToTable("Extras", ...) on an entity that is not mapped to any table (it is mapped only to a view, or is unmapped); declaring a view split when the entity has no main view mapping.

Common situations: Adding SplitToTable while the main mapping is missing or is a different store-object kind; copy-paste of split config into a keyless/unmapped type; refactor that removed the main ToTable.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/5200e97b202c118d. Report an issue: GitHub.

Appendix: source

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

        {
            return;
        }

        if (entityType.BaseType != null
            || entityType.GetDirectlyDerivedTypes().Any())
        {
            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(

View on GitHub (pinned to 3a2006ef56)