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 map any non-primary key property to it. Map at least one non-primary key property to a column on '{storeObject}'.

What it means

After confirming the key is fully mapped, the validator checks that the split fragment carries at least one NON-primary-key property. A fragment holding only the key columns (everything else unmapped) is meaningless and indicates a misconfiguration, so EF rejects it. propertiesFound must become true during the property loop.

Solutions

  1. Map at least one non-key property to the fragment: tb.Property(c => c.SomeColumn).HasColumnName("SomeColumn").
  2. If no payload belongs on that fragment, delete the SplitToTable / MappingFragment call entirely.
  3. Reconsider whether owned types or a one-to-one relationship express the intent better than an empty split.

Example fix

// before
modelBuilder.Entity<Order>()
    .SplitToTable("OrderKey", tb =>
    {
        tb.Property(o => o.OrderId).HasColumnName("OrderId"); // only the key -> [441]
    });

// after (add a payload column, or drop the fragment)
modelBuilder.Entity<Order>()
    .SplitToTable("OrderAudit", tb =>
    {
        tb.Property(o => o.OrderId).HasColumnName("OrderId");
        tb.Property(o => o.AuditNote).HasColumnName("AuditNote");
    });
Defensive patterns

Strategy: validation

Validate before calling

// After configuring a fragment, ensure at least one non-key property maps to it.
static bool FragmentHasPayload(IEntityType et, StoreObjectIdentifier store)
    => et.GetProperties().Any(p => !p.IsPrimaryKey() && p.GetColumnName(store) is not null);

Type guard

static bool IsValidSplitFragment(IEntityType et, StoreObjectIdentifier store)
    => et.FindPrimaryKey()!.Properties.All(p => p.GetColumnName(store) is not null)
       && et.GetProperties().Any(p => !p.IsPrimaryKey() && p.GetColumnName(store) is not null);

Prevention

When it happens

Trigger: A SplitToTable/MappingFragment where every non-key property resolves to a null column name on that fragment — e.g. only the PK was mapped (or implicitly inherited) and all payload columns were left on the main table or explicitly unmapped with .HasColumnName(null, fragment).

Common situations: Developer splits an entity but moves every payload property to the main table, leaving an empty fragment; misunderstanding entity splitting as a way to add a second key-only table; leftover fragment after refactoring.

Related errors


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

Appendix: source

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

                    if (property.IsPrimaryKey())
                    {
                        throw new InvalidOperationException(
                            RelationalStrings.EntitySplittingMissingPrimaryKey(
                                entityType.DisplayName(), fragment.StoreObject.DisplayName()));
                    }

                    continue;
                }

                if (!property.IsPrimaryKey())
                {
                    propertiesFound = true;
                }
            }

            if (!propertiesFound)
            {
                throw new InvalidOperationException(
                    RelationalStrings.EntitySplittingMissingProperties(
                        entityType.DisplayName(), fragment.StoreObject.DisplayName()));
            }

            switch (fragment.StoreObject.StoreObjectType)
            {
                case StoreObjectType.Table:
                    anyTableFragments = true;
                    break;
                case StoreObjectType.View:
                    anyViewFragments = true;
                    break;
            }
        }

        if (anyTableFragments)
        {
            ValidateMainMapping(entityType, StoreObjectIdentifier.Create(entityType, StoreObjectType.Table)!.Value);

View on GitHub (pinned to 3a2006ef56)