{"record":{"id":"620dd4bbf0be2223","repo":"dotnet/efcore","slug":"memberaccess-on-multi-dimensional-array","errorCode":null,"errorMessage":"MemberAccess on multi-dimensional array","messagePattern":"MemberAccess on multi-dimensional array","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs","lineNumber":804,"sourceCode":"        switch (memberInfo)\n        {\n            case Type nestedType:\n                return Constant(nestedType);\n\n            case null:\n                throw new InvalidOperationException($\"MemberAccess: couldn't find member '{memberSymbol.Name}': {memberAccess}\");\n        }\n\n        // Enum field constant\n        if (containingType.IsEnum)\n        {\n            return Constant(Enum.Parse(containingType, memberInfo.Name), containingType);\n        }\n\n        // array.Length\n        return expression.Type.IsArray && memberInfo.Name == \"Length\"\n            ? expression.Type.GetArrayRank() != 1\n                ? throw new NotImplementedException(\"MemberAccess on multi-dimensional array\")\n                : (Expression)ArrayLength(expression)\n            : MakeMemberAccess(\n                expression is ConstantExpression { Value: Type } ? null : expression,\n                memberInfo);\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    public override Expression VisitObjectCreationExpression(ObjectCreationExpressionSyntax objectCreation)\n    {\n        if (_semanticModel.GetSymbolInfo(objectCreation).Symbol is not IMethodSymbol constructorSymbol)\n        {\n            throw new InvalidOperationException($\"ObjectCreation: couldn't find IMethodSymbol for constructor: {objectCreation}\");\n        }","sourceCodeStart":786,"sourceCodeEnd":822,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs#L786-L822","documentation":"VisitMemberAccessExpression throws NotImplementedException when accessing .Length on a multi-dimensional array (rank != 1). Only single-dimensional array .Length is translatable to an ArrayLength expression.","triggerScenarios":"An expression like myMatrix.Length where myMatrix is declared as T[,] or any array with rank greater than 1, used inside a precompiled query.","commonSituations":"Grid/matrix/image-processing code that references the total length of a 2D array within a query.","solutions":["Use a jagged array (T[][]) instead of a multi-dimensional array","Hoist the array length out of the query into a captured int local","Flatten the data into a single-dimensional array"],"exampleFix":"// before\nint[,] grid = ...;\nvar q = ctx.Items.Where(i => i.Index < grid.Length);\n// after\nint total = grid.Length; // computed outside the query\nvar q = ctx.Items.Where(i => i.Index < total);","handlingStrategy":"validation","validationCode":"// Reject .Length on multi-dimensional arrays in precompiled query source.\n// Hoist the length into a captured local computed outside the query.\nint total = grid.Length; // outside\nvar q = ctx.Items.Where(i => i.Index < total);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer jagged arrays over multi-dimensional arrays for query data","Capture array lengths in locals before the query rather than reading .Length inside"],"tags":["efcore","precompiled-queries","arrays","csharp"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}