dotnet/efcore · error · NotImplementedException

ElementAccessExpressionSyntax over non-array

Error message

ElementAccessExpressionSyntax over non-array

What it means

In `VisitElementAccessExpression` the `default:` arm throws `NotImplementedException(ElementAccessExpressionSyntax over non-array)` when the receiver's converted type is neither `IArrayTypeSymbol` nor `INamedTypeSymbol` — i.e. an indexer over a type the translator does not model (e.g. pointer/indexer-on-dynamic).

Source

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

                    .GetProperties()
                    .Select(p => new { Property = p, IndexParameters = p.GetIndexParameters() })
                    .Where(t => t.IndexParameters.Length == arguments.Count
                        && t.IndexParameters
                            .Select(p => p.ParameterType)
                            .SequenceEqual(arguments.Select(a => ResolveType(a.Expression))))
                    .Select(t => t.Property)
                    .FirstOrDefault();

                Check.DebugAssert(property?.GetMethod is not null, "No matching property found for ElementAccessExpressionSyntax");

                return Call(visitedExpression, property.GetMethod, arguments.Select(a => Visit(a.Expression)));

            case null:
                throw new InvalidOperationException(
                    $"No type for expression {elementAccessExpression.Expression} in {nameof(ElementAccessExpressionSyntax)}");

            default:
                throw new NotImplementedException($"{nameof(ElementAccessExpressionSyntax)} over non-array");
        }
    }

    /// <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 VisitIdentifierName(IdentifierNameSyntax identifierName)
    {
        if (_parameterStack.Peek().TryGetValue(identifierName.Identifier.Text, out var parameter))
        {
            return parameter;
        }

        var symbol = _semanticModel.GetSymbolInfo(identifierName).Symbol;

View on GitHub (pinned to dbf9771522)

Solutions

  1. Index only over arrays or over types that expose a real indexer property.
  2. Hoist the access out of the query if it relies on pointer/dynamic semantics.

Example fix

// before
var q = ctx.Items.Where(i => ((dynamic)i.Extra)[key] != null);
// after
var extras = ctx.Items.Select(i => i.Extra).ToList();
var values = extras.Select(e => ((Dictionary<string,object>)e)[key]);
Defensive patterns

Strategy: validation

Validate before calling

// Only allow indexers over arrays or named types (with a real indexer property).
var converted = semanticModel.GetTypeInfo(elementAccess.Expression).ConvertedType;
if (converted is not (IArrayTypeSymbol or INamedTypeSymbol))
    throw new NotSupportedException(
        "Element access is only supported over arrays or types with an indexer; pointer/dynamic indexing is unsupported.");

translator.Translate(elementAccess, semanticModel);

Try / catch

try { translator.Translate(node, semanticModel); }
catch (NotImplementedException ex) when (ex.Message.Contains("ElementAccessExpressionSyntax over non-array"))
{ /* replace pointer/dynamic indexing with an indexer on a named type */ }

Prevention

When it happens

Trigger: An element access `x[i]` over a receiver whose converted type is something other than an array or a named type with an indexer (for example pointer indexing, `dynamic`, or an unbound symbol kind).

Common situations: Unsafe/pointer code or `dynamic` receivers appearing inside a precompiled query; rare in normal entity queries.

Related errors


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