dotnet/efcore · error · InvalidOperationException
The property ' . ' is a primitive collection of a primitive…
Error message
The property '{propertyType} {type}.{property}' is a primitive collection of a primitive collection. Nested primitive collections are not yet supported with relational database providers. What it means
ValidatePrimitiveCollection throws NestedCollectionsNotSupported when a property is a primitive collection whose element type mapping itself has a non-null ElementTypeMapping — i.e. a collection of collections (e.g. List<List<int>>, or int[][]). The relational provider can map a single-level primitive collection (to JSON or a native array column), but nested primitive collections are not yet implemented.
Solutions
- Flatten the nested collection into a single-level collection of a wrapper type (e.g. List<MatrixCell> with Row/Col/Value), mapped as a complex collection ToJson.
- Store the nested data as a string column with a HasConversion that serializes to JSON manually.
- Model the inner collection as a separate owned/JSON entity relationship rather than a primitive collection.
Example fix
// before
public class Matrix { public List<List<double>> Cells { get; set; } } // throws
// after — flatten to a complex collection
public class MatrixCell { public int Row { get; set; } public int Col { get; set; } public double Value { get; set; } }
public class Matrix { public List<MatrixCell> Cells { get; set; } = new(); }
modelBuilder.Entity<Matrix>().OwnsMany(m => m.Cells, c => c.ToJson()); Defensive patterns
Strategy: validation
Validate before calling
if (property is { IsPrimitiveCollection: true }
&& property.GetTypeMapping().ElementTypeMapping?.ElementTypeMapping != null)
throw new InvalidOperationException("Nested primitive collections are not supported."); Type guard
static bool IsNestedPrimitiveCollection(IProperty p)
=> p is { IsPrimitiveCollection: true }
&& p.GetTypeMapping().ElementTypeMapping?.ElementTypeMapping != null; Prevention
- Avoid List<List<T>> or T[][] properties on entities with relational providers.
- Flatten nested collections into a complex collection of wrapper records.
- Use HasConversion to serialize nested data to a string column if you must store it opaquely.
When it happens
Trigger: Declaring a property whose CLR type is IEnumerable<IEnumerable<T>> (or jagged arrays) on an entity. property.GetTypeMapping().ElementTypeMapping?.ElementTypeMapping != null is the nested-collection signature. Fires for any relational provider because the SQL generation cannot express nesting yet.
Common situations: Domain models with matrix/grid data (List<List<double>>); porting a model that relied on JSON serialization to store nested arrays; upgrading from a model that stored nested collections as opaque JSON strings via value converters.
Related errors
- Both properties ' ' and ' ' on entity type ' ' are mapped…
- Complex property ' ' cannot have both a JSON column name ('…
- Complex property ' ' cannot use 'HasJsonPropertyName()'…
- Complex property ' ' is mapped to JSON but its containing…
- The complex collection property
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/9480920dec89a242.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:254
ValidateDefaultValuesOnKey(key, logger);
ValidateValueGeneration(key, logger);
}
/// <summary>
/// Validates a primitive collection property.
/// </summary>
/// <param name="property">The property to validate.</param>
/// <param name="logger">The logger to use.</param>
protected override void ValidatePrimitiveCollection(
IProperty property,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
base.ValidatePrimitiveCollection(property, logger);
if (property is { IsPrimitiveCollection: true }
&& property.GetTypeMapping().ElementTypeMapping?.ElementTypeMapping != null)
{
throw new InvalidOperationException(
RelationalStrings.NestedCollectionsNotSupported(
property.ClrType.ShortDisplayName(), property.DeclaringType.DisplayName(), property.Name));
}
}
/// <inheritdoc />
protected override void ValidatePropertyMapping(
IComplexProperty complexProperty,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
base.ValidatePropertyMapping(complexProperty, logger);
if (complexProperty.IsCollection && !complexProperty.ComplexType.IsMappedToJson())
{
throw new InvalidOperationException(
RelationalStrings.ComplexCollectionNotMappedToJson(
complexProperty.DeclaringType.DisplayName(), complexProperty.Name));
}View on GitHub (pinned to 3a2006ef56)