dotnet/efcore · error · InvalidOperationException
The property '{propertyType} {type}.{property}' is a primiti
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 (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.
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 dbf9771522)
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.
Example fix
// before
public List<List<int>> Matrix { get; set; } // nested primitive collection -> throws
// after - wrap inner level in a complex type mapped to JSON
public class Row
{
public List<int> Values { get; set; } = new();
}
public List<Row> Matrix { get; set; } = new();
// modelBuilder.Entity<T>().OwnsMany(t => t.Matrix, r => r.ToJson("matrix")); Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in context.Model.GetEntityTypes())
{
foreach (var p in et.GetProperties().Where(p => p.IsPrimitiveCollection))
{
var mapping = p.GetTypeMapping();
if (mapping?.ElementTypeMapping?.ElementTypeMapping != null)
{
// will throw: nested primitive collection - flatten or wrap in complex type.
}
}
} Type guard
static bool IsNestedPrimitiveCollection(IProperty p)
=> p.IsPrimitiveCollection
&& p.GetTypeMapping().ElementTypeMapping?.ElementTypeMapping != null; Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The partition key property '{property1}' on '{entityType1}'
- Both properties '{property1}' and '{property2}' on entity ty
- The property '{property}' on type '{type}' is mapped to a JS
- The key {keyProperties} on the entity type '{entityType}' ca
- The complex collection property '{entityType}.{property}' mu
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/9480920dec89a242.
Report an issue: GitHub.