Union/Concat query with anonymous type and navigation property cannot be translated

Open
#21,480 2 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
csharp
Domain
databases

Research direction

Start with the LINQ repro in the issue and trace EF Core's query translation for Concat, anonymous projections, navigation-property access, and OrderBy. Done means the shown query translates and executes without the reported InvalidOperationException, with the behavior covered by a regression test if the relevant test location can be identified.

Written by the indexing model from the issue text.

Description

area-query area-set-operations customer-reported

This query cannot be translated:

_ =
    ctx.TestChildren.Where(c => c.Name == "Child 1").Select(c => new { c })
        .Concat(ctx.TestChildren.Where(c => c.Name == "Child 2").Select(c => new { c }))
        .Select(x => new { x.c, x.c.TestParent }) //Use c.TestParent
        .OrderBy(x => x.TestParent.Name) //Avoid client evaluation
        .ToList();
        
//

public partial class TestChild
{
    public int ID { get; set; }
    public int? TestParentID { get; set; }
    public string Name { get; set; }

    public virtual TestParent TestParent { get; set; }
}

public partial class TestParent
{
    public TestParent()
    {
        TestChildren = new HashSet<TestChild>();
    }

    public int ID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<TestChild> TestChildren { get; set; }
}
System.InvalidOperationException: 'The LINQ expression 'DbSet<TestChild>()
    .Where(t => t.Name == "Child 1")
    .Select(t => new { c = t })
    .Concat(DbSet<TestChild>()
        .Where(t0 => t0.Name == "Child 2")
        .Select(t0 => new { c = t0 }))
    .OrderBy(e => e.c.TestParent.Name)' could not be translated. Additional information: Translation of member 'TestParent' on entity type 'TestChild' failed. Possibly the specified member is not mapped.
Translation of member 'TestParent' on entity type 'TestChild' failed. Possibly the specified member is not mapped. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'

The repro depends on multiple properties of the query:

  1. Concat must be used.
  2. The sources for the concat must be wrapped in an anonymous type.
  3. The c.TestParent member must be accessed.
  4. I added an OrderBy to avoid client evaluation. If this is not done then c.TestParent is simply evaluated on the client in the final Select.

So the following does not throw:

_ =
    ctx.TestChildren.Where(c => c.Name == "Child 1")
        .Concat(ctx.TestChildren.Where(c => c.Name == "Child 2")) //Concat source not wrapped
        .Select(x => new { x, x.TestParent })
        .OrderBy(x => x.TestParent.Name) //Avoid client evaluation
        .ToList();

Tested in EF 5.0 preview 6.

Dominant language
C#
Stars
14.8k
Forks
3.4k
Avg merge
2d 5h
Merged PRs (30d)
134

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from dotnet/efcore

All issues in dotnet/efcore

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.