Skip to content

Interceptor not generated for LINQ operators after Select into anonymous type #9

@koenbeuk

Description

@koenbeuk

Description

When Select projects into an anonymous type, the resulting IRewritableQueryable<AnonymousType> has an anonymous element type. Subsequent delegate-based operators (e.g., OrderByDescending, Where) are not intercepted — the stub throws UnreachableException at runtime.

Reproduction

db.Orders
    .WithExpressionRewrite()
    .Where(o => o.Customer?.Name != null)
    .Select(o => new { o.Id, o.Total, o.Grade })
    .OrderByDescending(o => o.Total)  // throws UnreachableException
    .ToListAsync();

Error: UnreachableException: This method must be intercepted by the ExpressiveSharp source generator.

Root Cause

PolyfillInterceptorGenerator.TryEmit has an early guard at line ~290:

if (elementSymbol.IsAnonymousType)
    return null; // Anonymous element types can't be named in the interceptor body

This guard exists because the concrete (non-generic) interceptor code path can't name anonymous types. However, the generic code path (with T0, T1 type params) could handle this — it's already used for anonymous types in Select and other projection methods.

Workaround

Use a named type for the projection:

record OrderSummary(int Id, double Total, string Grade);

db.Orders.WithExpressionRewrite()
    .Where(o => o.Customer?.Name != null)
    .Select(o => new OrderSummary(o.Id, o.Total, o.Grade))
    .OrderByDescending(o => o.Total)  // works
    .ToListAsync();

Fix

Remove or relax the IsAnonymousType guard for element types. When the element type is anonymous, route all operators through the generic (anonymous-aware) code path that uses type parameters instead of concrete type names. This affects both the dedicated emitters and EmitGenericSingleLambda.

Found via stress test in samples/EFCoreSample/StressTest.cs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions