{"record":{"id":"6c55127e5b2a9d01","repo":"dotnet/efcore","slug":"invocation-over-non-member-access-invocation","errorCode":null,"errorMessage":"Invocation over non-member access: {invocation}","messagePattern":"Invocation over non-member access: (.+?)","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs","lineNumber":563,"sourceCode":"            throw new InvalidOperationException(\"Could not find symbol for method invocation: \" + invocation);\n        }\n\n        // First, if the method return type is the user's DbContext type (e.g. DbContext local variable, or field/property), return a\n        // constant over that DbContext type; the invocation can serve as the root for a LINQ query we can precompile.\n        if (methodSymbol.ReturnType.Equals(_userDbContextSymbol, SymbolEqualityComparer.Default))\n        {\n            return Constant(_userDbContext);\n        }\n\n        var declaringType = ResolveType(methodSymbol.ContainingType);\n\n        Expression? instance = null;\n        if (!methodSymbol.IsStatic || methodSymbol.IsExtensionMethod)\n        {\n            // In normal method calls (the ones we support), the invocation node is composed on top of a member access\n            if (invocation.Expression is not MemberAccessExpressionSyntax { Expression: var receiver })\n            {\n                throw new NotSupportedException($\"Invocation over non-member access: {invocation}\");\n            }\n\n            instance = Visit(receiver);\n        }\n\n        MethodInfo? methodInfo;\n\n        if (methodSymbol.IsGenericMethod)\n        {\n            var originalDefinition = methodSymbol.OriginalDefinition;\n            if (originalDefinition.ReducedFrom is not null)\n            {\n                originalDefinition = originalDefinition.ReducedFrom;\n            }\n\n            // To accurately find the right open generic method definition based on the Roslyn symbol, we need to create a mapping between\n            // generic type parameter names (based on the Roslyn side) and .NET reflection Types representing those type parameters.\n            // This includes both type parameters immediately on the generic method, as well as type parameters from the method's","sourceCodeStart":545,"sourceCodeEnd":581,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs#L545-L581","documentation":"Thrown when an instance method or extension method invocation's syntactic expression is not a MemberAccessExpressionSyntax. The translator assumes that for non-static (or extension) methods, the invocation sits on top of a member access like `receiver.Method(args)`. When the invocation node is something else — e.g. a parenthesized expression, a cast-then-call, or a delegate invocation — it throws NotSupportedException because it cannot extract the receiver expression.","triggerScenarios":"Calling a method through a cast or parenthesized expression that is not a direct member access: `((MyType)obj).Method()`, `((Func<int,int>)del)(5)` (delegate invocation), conditional access chains, or invoking a method on a parenthesized lambda result. Any invocation.Expression that is not a MemberAccessExpressionSyntax with a sub-expression triggers this.","commonSituations":"Developers who cast query sources or intermediate results inline, or who invoke delegates/groups directly. Common in complex projections where the developer casts an anonymous-typed intermediate or calls a method on a boxed/unboxed value. Also seen when using method group conversions inside query pipelines.","solutions":["Extract the cast or intermediate computation into a separate local variable so the method call becomes a clean member access on that variable: `var typed = (MyType)obj; typed.Method();`","Replace delegate invocations with direct method calls that Roslyn can resolve as member accesses.","Avoid parenthesized casts immediately before method calls inside precompiled query lambdas — break them into steps.","If using conditional access (x?.Method()), restructure to an explicit null check or use a helper method that the translator can visit normally."],"exampleFix":"// before\nvar query = ctx.Blogs.Where(b => ((dynamic)b.Meta).Active);\n\n// after\nvar query = ctx.Blogs.Where(b => b.Meta != null && b.Meta.Active);","handlingStrategy":"validation","validationCode":"// Before precompiling, check that instance method invocations are member accesses\nvar nonMemberInvocations = querySyntaxTree.DescendantNodes()\n    .OfType<InvocationExpressionSyntax>()\n    .Where(i =>\n    {\n        var symbol = semanticModel.GetSymbolInfo(i).Symbol as IMethodSymbol;\n        return symbol is { IsStatic: false } or { IsExtensionMethod: true }\n            && i.Expression is not MemberAccessExpressionSyntax;\n    });\nif (nonMemberInvocations.Any())\n    ReportError(\"Non-member-access invocations are not supported in precompiled queries\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid casts immediately before method calls inside precompiled query lambdas.","Replace delegate invocations (myFunc(x)) with direct named method calls.","Extract intermediate results into separate variables rather than using parenthesized casts inline.","Keep method chains simple: receiver.Method().OtherMethod() with no casts in between."],"tags":["precompiled-queries","roslyn","method-invocation","member-access","expression-tree"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}