dotnet/efcore · error · NotSupportedException
Lambda with null expression body
Error message
Lambda with null expression body
What it means
Thrown as NotSupportedException by VisitLambdaExpression when a lambda expression has a null ExpressionBody — meaning it is a statement lambda (a lambda with a block body containing statements) rather than an expression lambda (a single expression body). The translator can only convert expression-bodied lambdas into LINQ expression-tree LambdaExpressions. Statement lambdas would require full statement-to-expression-tree translation, which is not supported.
Solutions
- Rewrite the statement lambda as an expression lambda: extract any local variables into the expression using let-style chaining or inline them, and use ternary operators instead of if statements.
- Move complex logic that requires statements into a separate helper method and call it from the expression lambda (ensure the method is translatable).
- Replace if-else logic with conditional (ternary) expressions: `b => b.Id > 0 ? b.Name : null`.
- Replace local variable computations with method chaining: instead of `b => { var x = b.Salary * 2; return x > 1000; }` use `b => b.Salary * 2 > 1000`.
- Remove any debugging code (Console.WriteLine, logging) from lambdas inside precompiled queries.
Example fix
// before — statement lambda
var query = ctx.Blogs.Where(b =>
{
var adjusted = b.Score * b.Weight;
return adjusted > 100;
});
// after — expression lambda
var query = ctx.Blogs.Where(b => b.Score * b.Weight > 100); Defensive patterns
Strategy: validation
Validate before calling
// Before precompiling, scan for statement lambdas (block-bodied lambdas)
var statementLambdas = querySyntaxTree.DescendantNodes()
.Where(n => n is SimpleLambdaExpressionSyntax or ParenthesizedLambdaExpressionSyntax)
.Cast<AnonymousFunctionExpressionSyntax>()
.Where(l => l.ExpressionBody is null); // null ExpressionBody means block body
if (statementLambdas.Any())
ReportError("Statement lambdas (block bodies) are not supported in precompiled queries — use expression lambdas"); Type guard
// Type guard to distinguish expression lambdas from statement lambdas (Roslyn CSharpSyntaxVisitor level)
// ExpressionBody is non-null for expression lambdas, null for statement lambdas
static bool IsExpressionLambda(AnonymousFunctionExpressionSyntax lambda)
=> lambda.ExpressionBody is not null;
// Usage before precompilation:
// if (!IsExpressionLambda(lambdaNode)) skipPrecompilation(lambdaNode); Prevention
- Always use expression-bodied lambdas (single expression, no braces) in precompiled queries.
- Replace if-else logic inside lambdas with ternary operators (?:).
- Inline local variables directly into the expression or compute them before the query.
- Remove debugging/logging statements from precompiled query lambdas.
- Extract multi-step logic into separate helper methods called from the expression lambda.
- Use the IDE to collapse statement lambdas into expression lambdas before enabling precompilation.
When it happens
Trigger: A precompiled query contains a lambda with a statement block body instead of a single expression: `ctx.Blogs.Where(b => { var x = b.Id + 1; return x > 10; })`. The translator's VisitLambdaExpression checks `lambda.ExpressionBody is null` (which is true for block-bodied lambdas) and throws NotSupportedException.
Common situations: Developers who use statement lambdas for complex logic inside LINQ calls; refactoring expression lambdas into statement lambdas during debugging (adding logging, breakpoints); multi-line predicates that were written as blocks for readability; code produced by refactoring tools that convert expressions to statement blocks; developers unfamiliar with the expression-tree limitation on statement lambdas.
Related errors
- LINQ query comprehension syntax is currently not supported…
- ArrayCreation: multi-dimensional array
- Could not find symbol for method invocation
- Could not find symbol for typeof() expression
- Couldn't find single Add method on type
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/50e7f181d3b07b3c.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:1032
var type = ResolveType(typeSymbol);
return Constant(type, typeof(Type));
}
/// <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 DefaultVisit(SyntaxNode node)
=> throw new NotSupportedException($"Unsupported syntax node of type '{node.GetType()}': {node}");
private Expression VisitLambdaExpression(AnonymousFunctionExpressionSyntax lambda, Type? expectedType = null)
{
if (lambda.ExpressionBody is null)
{
throw new NotSupportedException("Lambda with null expression body");
}
if (lambda.Modifiers.Any())
{
throw new NotSupportedException("Lambda with modifiers not supported: " + lambda.Modifiers);
}
if (!lambda.AsyncKeyword.IsKind(SyntaxKind.None))
{
throw new NotSupportedException("Async lambdas are not supported");
}
var lambdaParameters = lambda switch
{
SimpleLambdaExpressionSyntax simpleLambda => SyntaxFactory.SingletonSeparatedList(simpleLambda.Parameter),
ParenthesizedLambdaExpressionSyntax parenthesizedLambda => parenthesizedLambda.ParameterList.Parameters,
_ => throw new UnreachableException()View on GitHub (pinned to 3a2006ef56)