{"record":{"id":"a806de288a1a16b9","repo":"dotnet/efcore","slug":"entity-type-entitytype-has-a-split-mapping-and","errorCode":null,"errorMessage":"Entity type '{entityType}' has a split mapping and is an optional dependent sharing a store object, but it doesn't map any required non-shared property to the main store object. Keep at least one required non-shared property mapped to a column on '{storeObject}' or mark '{entityType}' as a required dependent by calling '{requiredDependentConfig}'.","messagePattern":"Entity type '(.+?)' has a split mapping and is an optional dependent sharing a store object, but it doesn't map any required non-shared property to the main store object\\. Keep at least one required non-shared property mapped to a column on '(.+?)' or mark '(.+?)' as a required dependent by calling '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":2503,"sourceCode":"                        && !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>\n    ///     Validates a table-specific property override for a property.\n    /// </summary>\n    /// <param name=\"property\">The property to validate.</param>\n    /// <param name=\"propertyOverride\">The property override to validate.</param>\n    /// <param name=\"logger\">The logger to use.</param>\n    protected virtual void ValidatePropertyOverride(\n        IProperty property,\n        IReadOnlyRelationalPropertyOverrides propertyOverride,","sourceCodeStart":2485,"sourceCodeEnd":2521,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L2485-L2521","documentation":"When the entity is an optional dependent that shares a store object (table splitting), an all-NULL row is indistinguishable from 'no dependent'. To disambiguate, the validator requires at least one REQUIRED (non-nullable), non-shared property mapped to the main store object. If none is found and a row-internal FK is not IsRequiredDependent, it throws and tells you how to mark the dependent required.","triggerScenarios":"An owned/dependent entity configured as optional (nullable navigation) that also uses split mapping, where every property on the main store object is either nullable or shared from the principal (FindSharedStoreObjectRootProperty != null), so nonSharedRequiredPropertyFound stays false.","commonSituations":"Nullable owned navigations in table splitting with only nullable columns; refactor that made all columns nullable; TPT/TPH sharing where dependent columns overlap the principal.","solutions":["Add a required (non-nullable), non-shared property mapped to the main store object so a dependent row is always detectable.","Mark the dependent as required exactly as the message suggests: modelBuilder.Entity<Principal>().OwnsOne(p => p.Dependent).Navigation(p => p.Dependent).IsRequired() (or HasPrincipalKey/required navigation) so IsRequiredDependent becomes true.","Make an existing nullable column non-nullable if business rules allow."],"exampleFix":"// before — optional dependent, all columns nullable -> [443]\nmodelBuilder.Entity<Order>()\n    .OwnsOne(o => o.BillingInfo, b =>\n    {\n        b.Property(bi => bi.TaxId).IsRequired(false);\n        b.ToTable(\"Order\");\n    });\n\n// after — mark the owned navigation required\nmodelBuilder.Entity<Order>()\n    .OwnsOne(o => o.BillingInfo, b =>\n    {\n        b.Property(bi => bi.TaxId).IsRequired();\n        b.ToTable(\"Order\");\n    })\n    .Navigation(o => o.BillingInfo)\n    .IsRequired();","handlingStrategy":"validation","validationCode":"// For an optional dependent sharing a table, ensure a required non-shared property OR mark required.\nstatic bool OptionalDependentIsDistinguishable(IEntityType et, StoreObjectIdentifier main)\n{\n    if (et.FindRowInternalForeignKeys(main).All(fk => fk.IsRequiredDependent))\n        return true;\n    return et.GetProperties().Any(p =>\n        !p.IsPrimaryKey()\n        && !p.IsNullable\n        && p.GetColumnName(main) is not null\n        && p.FindSharedStoreObjectRootProperty(main) is null);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give optional dependents at least one non-nullable, non-shared column on the shared table.","Prefer marking owned navigations required (.Navigation(...).IsRequired()) when the dependent always exists.","Avoid all-nullable owned type column sets in table splitting."],"tags":["entity-splitting","optional-dependent","owned-types","model-validation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}