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

  1. Flatten the structure into a single primitive collection (List<int>) and store dimensions/structure separately.
  2. 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.
  3. 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

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


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/9480920dec89a242. Report an issue: GitHub.