dotnet/efcore · error · NotImplementedException

MemberAccess on multi-dimensional array

Error message

MemberAccess on multi-dimensional array

What it means

VisitMemberAccessExpression throws NotImplementedException when accessing .Length on a multi-dimensional array (rank != 1). Only single-dimensional array .Length is translatable to an ArrayLength expression.

Source

Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:804

        switch (memberInfo)
        {
            case Type nestedType:
                return Constant(nestedType);

            case null:
                throw new InvalidOperationException($"MemberAccess: couldn't find member '{memberSymbol.Name}': {memberAccess}");
        }

        // Enum field constant
        if (containingType.IsEnum)
        {
            return Constant(Enum.Parse(containingType, memberInfo.Name), containingType);
        }

        // array.Length
        return expression.Type.IsArray && memberInfo.Name == "Length"
            ? expression.Type.GetArrayRank() != 1
                ? throw new NotImplementedException("MemberAccess on multi-dimensional array")
                : (Expression)ArrayLength(expression)
            : MakeMemberAccess(
                expression is ConstantExpression { Value: Type } ? null : expression,
                memberInfo);
    }

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public override Expression VisitObjectCreationExpression(ObjectCreationExpressionSyntax objectCreation)
    {
        if (_semanticModel.GetSymbolInfo(objectCreation).Symbol is not IMethodSymbol constructorSymbol)
        {
            throw new InvalidOperationException($"ObjectCreation: couldn't find IMethodSymbol for constructor: {objectCreation}");
        }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Use a jagged array (T[][]) instead of a multi-dimensional array
  2. Hoist the array length out of the query into a captured int local
  3. Flatten the data into a single-dimensional array

Example fix

// before
int[,] grid = ...;
var q = ctx.Items.Where(i => i.Index < grid.Length);
// after
int total = grid.Length; // computed outside the query
var q = ctx.Items.Where(i => i.Index < total);
Defensive patterns

Strategy: validation

Validate before calling

// Reject .Length on multi-dimensional arrays in precompiled query source.
// Hoist the length into a captured local computed outside the query.
int total = grid.Length; // outside
var q = ctx.Items.Where(i => i.Index < total);

Prevention

When it happens

Trigger: An expression like myMatrix.Length where myMatrix is declared as T[,] or any array with rank greater than 1, used inside a precompiled query.

Common situations: Grid/matrix/image-processing code that references the total length of a 2D array within a query.

Related errors


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