{"record":{"id":"2d8098c2983dee60","repo":"dotnet/efcore","slug":"entity-type-entitytype-has-a-split-mapping-bu","errorCode":null,"errorMessage":"Entity type '{entityType}' has a split mapping, but it doesn't map any non-primary key property to the main store object. Keep at least one non-primary key property mapped to a column on '{storeObject}'.","messagePattern":"Entity type '(.+?)' has a split mapping, but it doesn't map any non-primary key property to the main store object\\. Keep at least one non-primary key property mapped to a column on '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":2495,"sourceCode":"                }\n\n                var columnName = property.GetColumnName(mainObject);\n                if (columnName != null)\n                {\n                    propertyFound = true;\n\n                    if (!nonSharedRequiredPropertyFound\n                        && !property.IsNullable\n                        && property.FindSharedStoreObjectRootProperty(mainObject) == null)\n                    {\n                        nonSharedRequiredPropertyFound = true;\n                    }\n                }\n            }\n\n            if (!propertyFound)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.EntitySplittingMissingPropertiesMainFragment(\n                        entityType.DisplayName(), mainObject.DisplayName()));\n            }\n\n            if (!nonSharedRequiredPropertyFound)\n            {\n                var rowInternalFk = entityType.FindRowInternalForeignKeys(mainObject).First(fk => !fk.IsRequiredDependent);\n                throw new InvalidOperationException(\n                    RelationalStrings.EntitySplittingMissingRequiredPropertiesOptionalDependent(\n                        entityType.DisplayName(), mainObject.DisplayName(),\n                        $\".Navigation(p => p.{rowInternalFk.PrincipalToDependent!.Name}).IsRequired()\"));\n            }\n\n            return mainObject;\n        }\n    }\n\n    /// <summary>","sourceCodeStart":2477,"sourceCodeEnd":2513,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L2477-L2513","documentation":"ValidateMainMapping walks the MAIN store object (the entity's primary table/view). It requires at least one non-key property still mapped there (propertyFound). If every non-key property has been moved onto split fragments so the main object holds only the key, the mapping is rejected — entity splitting must leave payload on the main table.","triggerScenarios":"Splitting an entity and unmapping every non-PK property from the main table (e.g. .HasColumnName(null) on the default table for all payload properties while mapping them only to SplitToTable fragments), so propertyFound stays false inside ValidateMainMapping.","commonSituations":"Over-aggressive splitting; treating the main table as a pure key/join table; bugs in code-generated mapping where the main ToTable loses its columns.","solutions":["Keep at least one non-key property mapped to the main store object (do not null-out all payload columns on the default table).","Audit table-specific overrides on the default ToTable to confirm none of them strip every payload column.","If the intent really is a key-only root, redesign with owned types or a separate entity instead of splitting."],"exampleFix":"// before — every payload column unmapped on main table\nmodelBuilder.Entity<Invoice>()\n    .ToTable(\"Invoice\", tb =>\n    {\n        tb.Property(i => i.Amount).HasColumnName(null);\n        tb.Property(i => i.Note).HasColumnName(null);\n    })\n    .SplitToTable(\"InvoiceDetail\", tb =>\n    {\n        tb.Property(i => i.Id).HasColumnName(\"Id\");\n        tb.Property(i => i.Amount).HasColumnName(\"Amount\");\n        tb.Property(i => i.Note).HasColumnName(\"Note\");\n    }); // main has only Id -> [442]\n\n// after — keep a payload column on the main table\nmodelBuilder.Entity<Invoice>()\n    .ToTable(\"Invoice\", tb => tb.Property(i => i.Amount).HasColumnName(\"Amount\"))\n    .SplitToTable(\"InvoiceDetail\", tb =>\n    {\n        tb.Property(i => i.Id).HasColumnName(\"Id\");\n        tb.Property(i => i.Note).HasColumnName(\"Note\");\n    });","handlingStrategy":"validation","validationCode":"// Verify the main store object keeps at least one non-key property.\nstatic bool MainHasPayload(IEntityType et, StoreObjectIdentifier main)\n    => et.GetProperties().Any(p => !p.IsPrimaryKey() && p.GetColumnName(main) is not null);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not unmapping every payload column off the default ToTable when using splitting.","Audit table-specific overrides on the main table after refactoring.","Add a unit test that builds the model and asserts main-table payload presence."],"tags":["entity-splitting","model-validation","relational"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}