{"record":{"id":"2921355b0183c327","repo":"dotnet/efcore","slug":"the-index-indexproperties-on-the-entity-type-e-292135","errorCode":null,"errorMessage":"The index {indexProperties} on the entity type '{entityType}' cannot contain the complex property '{property}' because it's mapped to multiple columns. Reference each scalar property of the complex type individually instead.","messagePattern":"The index (.+?) on the entity type '(.+?)' cannot contain the complex property '(.+?)' because it's mapped to multiple columns\\. Reference each scalar property of the complex type individually instead\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":2778,"sourceCode":"\n        if (inJsonComplex)\n        {\n            return;\n        }\n\n        base.ValidateIndexProperty(index, property, logger);\n    }\n\n    /// <inheritdoc />\n    protected override void ValidateIndexOnComplexProperty(\n        IIndex index,\n        IReadOnlyList<IComplexProperty> complexProperties,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        var nonJsonComplexProperty = complexProperties.FirstOrDefault(cp => !cp.ComplexType.IsMappedToJson());\n        if (nonJsonComplexProperty != null)\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.IndexOnNonJsonComplexProperty(\n                    index.Properties.Format(),\n                    index.DeclaringEntityType.DisplayName(),\n                    nonJsonComplexProperty.Name));\n        }\n\n        if (index.IsUnique)\n        {\n            // Currently not supported. We have special logic for unique indexes in the update pipeline\n            // and query that would need to be updated to support this.\n            throw new InvalidOperationException(\n                RelationalStrings.UniqueIndexOnComplexProperty(\n                    index.Properties.Format(),\n                    index.DeclaringEntityType.DisplayName(),\n                    complexProperties[0].Name));\n        }\n    }\n","sourceCodeStart":2760,"sourceCodeEnd":2796,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L2760-L2796","documentation":"An index can reference a complex property as a single unit only when that complex type is mapped to JSON (one column). A non-JSON complex property fans out to multiple columns, so one index cannot represent it. The validator (ValidateIndexOnComplexProperty) finds the first non-JSON complex property in the index path and throws, telling you to reference each scalar sub-property individually.","triggerScenarios":"Calling .HasIndex(e => e.Address) where Address is a complex property whose complex type is NOT mapped to JSON (it maps to multiple columns).","commonSituations":"Indexing a value-object/struct that is mapped to columns; misunderstanding complex types vs entities; copying a JSON-style index onto a column-mapped complex type.","solutions":["Reference scalar sub-properties of the complex type individually: .HasIndex(e => e.Address!.ZipCode).","If you genuinely want one index over the whole value object, map the complex type to JSON (.ToJson) so it occupies a single column.","Split the index so each column is named explicitly."],"exampleFix":"// before — indexing a non-JSON complex property -> [446]\nmodelBuilder.Entity<Customer>()\n    .ComplexProperty(c => c.Address)\n    .HasIndex(c => c.Address); // Address spans many columns\n\n// after — index scalar sub-properties\nmodelBuilder.Entity<Customer>()\n    .ComplexProperty(c => c.Address);\nmodelBuilder.Entity<Customer>().HasIndex(c => c.Address.ZipCode);","handlingStrategy":"validation","validationCode":"// Before indexing a complex property, ensure it is JSON-mapped or index its scalar leaves.\nstatic bool CanIndexComplexPropertyAsUnit(IReadOnlyComplexProperty cp)\n    => cp.ComplexType.IsMappedToJson();","typeGuard":"static bool IsComplexPropertyJsonMapped(IReadOnlyComplexProperty cp)\n    => cp.ComplexType.IsMappedToJson();","tryCatchPattern":null,"preventionTips":["Prefer indexing scalar sub-properties of complex types over indexing the whole complex property.","Map a complex type to JSON only if you genuinely need it as a single indexable unit.","Add a test that builds the model to catch index-on-complex mistakes early."],"tags":["complex-types","indexes","model-validation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}