{"record":{"id":"9480920dec89a242","repo":"dotnet/efcore","slug":"the-property-propertytype-type-property-is","errorCode":null,"errorMessage":"The property '{propertyType} {type}.{property}' is a primitive collection of a primitive collection. Nested primitive collections are not yet supported with relational database providers.","messagePattern":"The property '(.+?) (.+?)\\.(.+?)' is a primitive collection of a primitive collection\\. Nested primitive collections are not yet supported with relational database providers\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":254,"sourceCode":"        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,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        base.ValidatePrimitiveCollection(property, logger);\n\n        if (property is { IsPrimitiveCollection: true }\n            && property.GetTypeMapping().ElementTypeMapping?.ElementTypeMapping != null)\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.NestedCollectionsNotSupported(\n                    property.ClrType.ShortDisplayName(), property.DeclaringType.DisplayName(), property.Name));\n        }\n    }\n\n    /// <inheritdoc />\n    protected override void ValidatePropertyMapping(\n        IComplexProperty complexProperty,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        base.ValidatePropertyMapping(complexProperty, logger);\n\n        if (complexProperty.IsCollection && !complexProperty.ComplexType.IsMappedToJson())\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.ComplexCollectionNotMappedToJson(\n                    complexProperty.DeclaringType.DisplayName(), complexProperty.Name));\n        }","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L236-L272","documentation":"ValidatePrimitiveCollection (RelationalModelValidator.cs:251-257) throws when a primitive-collection property's type mapping is itself a primitive collection of a primitive collection (mapping.ElementTypeMapping?.ElementTypeMapping != null). Relational providers can store a flat list of primitives (as a JSON/array column) but cannot yet store nested arrays/lists, so a doubly-nested primitive collection is rejected at validation.","triggerScenarios":"Mapping a property like List<List<int>>, int[][], or IEnumerable<IEnumerable<string>> on an entity with a relational provider. The outer element maps to a primitive collection and its element is again a primitive collection, tripping the nested-collection check.","commonSituations":"Domain models with matrix/grid data (List<List<double>>), jagged arrays, or nested tag buckets; porting a document-store model that allowed nested arrays to EF Core relational.","solutions":["Flatten the structure into a single primitive collection (List<int>) and store dimensions/structure separately.","Wrap the inner collection in an entity or complex type and map the collection of that type to JSON (ToJson), so only one level of primitive collection exists.","Serialize the nested structure into a single string/JSON column with a value converter."],"exampleFix":"// before\npublic List<List<int>> Matrix { get; set; } // nested primitive collection -> throws\n\n// after - wrap inner level in a complex type mapped to JSON\npublic class Row\n{\n    public List<int> Values { get; set; } = new();\n}\npublic List<Row> Matrix { get; set; } = new();\n// modelBuilder.Entity<T>().OwnsMany(t => t.Matrix, r => r.ToJson(\"matrix\"));","handlingStrategy":"validation","validationCode":"foreach (var et in context.Model.GetEntityTypes())\n{\n    foreach (var p in et.GetProperties().Where(p => p.IsPrimitiveCollection))\n    {\n        var mapping = p.GetTypeMapping();\n        if (mapping?.ElementTypeMapping?.ElementTypeMapping != null)\n        {\n            // will throw: nested primitive collection - flatten or wrap in complex type.\n        }\n    }\n}","typeGuard":"static bool IsNestedPrimitiveCollection(IProperty p)\n    => p.IsPrimitiveCollection\n       && p.GetTypeMapping().ElementTypeMapping?.ElementTypeMapping != null;","tryCatchPattern":null,"preventionTips":["Avoid List<List<T>>/T[][] properties; flatten or wrap inner levels in a complex/entity type.","Store nested matrices via a value converter serializing to JSON/string.","Review new collection properties against the single-level primitive rule."],"tags":["primitive-collection","nested-collection","json-mapping","model-validation"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}