Skip to content

LINQ: the in-memory rewriter cache keeps captured variables from the first call, so later queries return stale results #207

Closed

Description

@mrdevrobot

Version: main (efacaf4), platform-independent.

What happens

ExecuteViaEnumerableRewriter caches the compiled delegate under typeof(TResult).FullName + expression.ToString() (BTreeQueryProvider.cs:702-726). ToString() prints a captured variable as the closure field access, not its value, and the quoted lambdas are compiled with the first call's closure object baked in. A later call with a different captured value reuses that delegate and returns the first call's result. No error is raised.

Repro

300 PersonV2 documents with Age = i % 50:

int F(IQueryable<PersonV2> q, int t) => q.Count(p => p.Age > t);

F(db.PeopleV2.AsQueryable(), 5);   // 264, correct
F(db.PeopleV2.AsQueryable(), 40);  // 264, expected 54
F(db.PeopleV2.AsQueryable(), 1);   // 264, expected 288

The same happens with Where(...).Count(pred) and with every other shape that falls back to the rewriter. Open PRs #180 and #193 route more shapes through it (Select(...).Count(a => a > t), OrderBy(idx).Take(20).Count(p => p.Age < t)).

Expected

Each call uses its own captured values.

Possible fix

Key the cache on the expression shape with closure constants replaced by parameters, and pass the captured values in as arguments at execution; or don't cache delegates for expressions that contain closure constants.

Activity

  1. added this to the 5.3.0 milestone on Oct 15, 2026
  2. added
    bugSomething isn't working
    area/linqLINQ provider, expression visitor, rewriter
    severity/criticalData loss, corruption, or silently wrong results in common use
    priority/P0Fix before anything else; blocks the next release
    and removed on Oct 15, 2026
  3. moved this from Todo to In Progress in BLiteon Oct 15, 2026
  4. moved this from In Progress to Done in BLiteon Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/linqLINQ provider, expression visitor, rewriterbugSomething isn't workingpackage/coreAffects BLite.Corepriority/P0Fix before anything else; blocks the next releaseseverity/criticalData loss, corruption, or silently wrong results in common use

    Type

    No type

    Projects

    • Status
      Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions