ExportXMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Unknown
    • 10.0.4, 9.1.4, 8.4.4
    • Affects Version/s: None
    • Component/s: None
    • None
    • None
    • Dotnet Drivers
    • Not Needed
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      GetLookupAlias derives a $lookup alias from the navigation name only, and AddLookup de-duplicates on As. When two hops of a query derive the same alias, only one $lookup can ever be emitted no matter what localField prefix it carries. This makes sibling {{ThenInclude}}s over two same-typed navigations impossible to translate natively.

      Measured 2026-08-05 while implementing EF-372 (branch EF-372, EF10, real atlas-local container).

      Repro

      Model: Root.PrimaryMid and Root.SecondaryMid both reference Mid; Mid.Leaf references Leaf.

      Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      db.Roots.Include(r => r.PrimaryMid).ThenInclude(m => m.Leaf)
              .Include(r => r.SecondaryMid).ThenInclude(m => m.Leaf)
      

      Before EF-372: returned PrimaryMid.Leaf.Label == "A", SecondaryMid.Leaf == null — silently wrong data, with the two seeded leaves pointing at different targets.

      After EF-372: declines translation cleanly (return null, EF Core's translation-failure path). Pinned by Two_same_typed_navigations_sibling_ThenIncludes_decline_cleanly in tests/MongoDB.EntityFrameworkCore.FunctionalTests/Query/Ef372DeepReferenceIncludeTests.cs, which asserts the decline and documents why.

      Note the related shapes that do work after EF-372, so this ticket is specifically about the sibling case:

      • Single-branch Include(PrimaryMid).ThenInclude(Leaf) on the same model — correct rows.
      • Single-branch Include(SecondaryMid).ThenInclude(Leaf) alone — correct rows (previously returned SecondaryMid == null, silently wrong).

      Root cause

      Both sibling hops derive the identical alias from the same navigation name (Leaf), so AddLookup's de-dup on As drops one of them. The localField prefix work in EF-372 scopes where a lookup reads from; it cannot help when the lookup was never emitted.

      Fix shape

      A path-scoped alias scheme: aliases must encode the navigation path to the hop, not just the leaf navigation name, so PrimaryMid.Leaf and SecondaryMid.Leaf produce distinct aliases. This is a broader change than EF-372 and was deliberately kept out of that slice.

      Any fix must keep the EF-372 invariant intact — a transitive hop's localField is scoped to the alias of the lookup that produced its intermediate — and must not disturb the contiguous-lookup-group reasoning at MongoEFToLinqTranslatingExpressionVisitor.LeftJoin.cs:695, which EF-373 depends on.

      Status

      Unreleased: the whole native transitive-join path postdates v10.0.2 / v9.1.2 / v8.4.2 (it arrived with efb5f256, EF-117). At those release tags any cross-collection Include/Join throws, so no shipped behavior is affected and no BREAKING-CHANGES.md entry applies.

      The decline is a hard translation failure in every MongoQueryMode, including explicit DriverLinq — UseQueryMode is not an escape hatch. This is structural rather than an oversight: a transitive hop is always a second-or-later join, so lookups are registered at translation time before MongoQueryMode is read, and both paths are already committed to the flat lookup<Nav> shape. A graceful MarkNotNativelyRepresentable() was tried and measured worse — the un-rebound inner shaper reaches materialization and throws Document element is missing for required non-nullable property 'Label' under both Native and DriverLinq.

            Assignee:
            Arthur Vickers
            Reporter:
            Arthur Vickers
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: