{"record":{"id":"9244b03da75a397b","repo":"dotnet/efcore","slug":"the-key-keyproperties-on-the-entity-type-entit","errorCode":null,"errorMessage":"The key {keyProperties} on the entity type '{entityType}' cannot be configured because the property '{property}' is contained in a complex type mapped to a JSON column. Keys cannot reference properties that are stored inside a JSON document.","messagePattern":"The key (.+?) on the entity type '(.+?)' cannot be configured because the property '(.+?)' is contained in a complex type mapped to a JSON column\\. Keys cannot reference properties that are stored inside a JSON document\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":228,"sourceCode":"        {\n            throw new InvalidOperationException(\n                RelationalStrings.AutoLoadedJsonProperty(property.Name, structuralType.DisplayName()));\n        }\n    }\n\n    /// <inheritdoc />\n    protected override void ValidateKey(\n        IKey key,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        base.ValidateKey(key, logger);\n\n        foreach (var property in key.Properties)\n        {\n            if (property.DeclaringType is IComplexType complexType\n                && complexType.IsMappedToJson())\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.KeyPropertyInJsonComplexType(\n                        key.Properties.Format(),\n                        key.DeclaringEntityType.DisplayName(),\n                        property.Name));\n            }\n        }\n\n        ValidateDefaultValuesOnKey(key, logger);\n        ValidateValueGeneration(key, logger);\n    }\n\n    /// <summary>\n    ///     Validates a primitive collection property.\n    /// </summary>\n    /// <param name=\"property\">The property to validate.</param>\n    /// <param name=\"logger\">The logger to use.</param>\n    protected override void ValidatePrimitiveCollection(\n        IProperty property,","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L210-L246","documentation":"ValidateKey throws KeyPropertyInJsonComplexType when any property of a key is declared on a complex type that is mapped to a JSON column. Keys are relational concepts that must map to real columns; a property stored inside a JSON document cannot participate in a primary/alternate key, so the validator blocks this at finalization.","triggerScenarios":"Defining a key (HasKey) where one of the key properties lives on a ComplexType whose ComplexProperty is configured with ToJson. The check iterates key.Properties and inspects each property.DeclaringType — if it is IComplexType && complexType.IsMappedToJson(), the key is rejected.","commonSituations":"Promoting a nested JSON property to part of a key after switching to ToJson mapping; scaffolding code that adds keys to complex types before configuring JSON; value objects used as keys then migrated into a JSON column.","solutions":["Move the key property out of the JSON-mapped complex type onto the owning entity as a real column.","Drop the HasKey call referencing properties inside the JSON complex type; keys cannot live in JSON.","If you need identity over JSON content, store a derived real column (e.g. a hash) and key on that instead."],"exampleFix":"// before\nmodelBuilder.Entity<Customer>()\n    .OwnsOne(c => c.Address, a =>\n    {\n        a.ToJson(\"address\");\n        a.Property(p => p.PostalCode);\n    });\nmodelBuilder.Entity<Customer>().HasAlternateKey(c => c.Address.PostalCode); // throws\n\n// after — promote to a real column on Customer\nmodelBuilder.Entity<Customer>().Property(c => c.PostalCode).HasColumnName(\"postal_code\");\nmodelBuilder.Entity<Customer>().HasAlternateKey(c => c.PostalCode);","handlingStrategy":"validation","validationCode":"foreach (var keyProp in key.Properties)\n    if (keyProp.DeclaringType is IComplexType ct && ct.IsMappedToJson())\n        throw new InvalidOperationException($\"Key property {keyProp.Name} is in a JSON complex type.\");","typeGuard":"static bool KeyReferencesJsonProperty(IKey k)\n    => k.Properties.Any(p => p.DeclaringType is IComplexType ct && ct.IsMappedToJson());","tryCatchPattern":null,"preventionTips":["Never define keys (HasKey) over properties inside a JSON-mapped complex type.","Promote identifying properties onto the owning entity as real columns before keying.","When converting owned types to JSON, audit existing HasKey/HasAlternateKey calls."],"tags":["json-mapping","keys","complex-type","model-validation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}