Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I can't add a defining query that uses a left join #19845

Closed
ChannelSix opened this issue Feb 8, 2020 · 4 comments
Closed

I can't add a defining query that uses a left join #19845

ChannelSix opened this issue Feb 8, 2020 · 4 comments

Comments

@ChannelSix
Copy link

If I create a defining query that uses a left join in EF Core v3.1.1 I get the exception below when attempting to query the defining query. Note that I can't use navigation properties on my actual models.

If I run the exact same expression through a normal query it runs fine.

Steps to reproduce

    class Program
    {
        static async Task Main(string[] args)
        {
            var context = new Context();
            var adHocQuery = from p in context.Set<Parent>()
                        join c in context.Set<Child>() on p.Id equals c.ParentId into outer
                        from cLeft in outer
                        select new ParentChild
                        {
                            ParentId = p.Id,
                            ParentName = p.Name,
                            ChildId = cLeft == null ? (int?)null : cLeft.Id,
                            ChildName = cLeft == null ? null : cLeft.Name
                        };
            var adHocQueryResult = await adHocQuery.ToArrayAsync();
            var joined = await context.Set<ParentChild>().ToArrayAsync();
        }
    }

    public class Parent
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class Child
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int ParentId { get; set; }
    }

    public class ParentChild
    {
        public int ParentId { get; set; }
        public string ParentName { get; set; }
        public int? ChildId { get; set; }
        public string ChildName { get; set; }
    }

    public class Context : DbContext
    {
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Parent>()
                .HasKey(p => p.Id);
            modelBuilder.Entity<Child>()
                .HasKey(c => c.Id);

            modelBuilder.Entity<ParentChild>()
                .HasNoKey()
                .ToQuery(() =>
                    from p in Set<Parent>()
                    join c in Set<Child>() on p.Id equals c.ParentId into outer
                    from cLeft in outer
                    select new ParentChild
                    {
                        ParentId = p.Id,
                        ParentName = p.Name,
                        ChildId = cLeft == null ? (int?)null : cLeft.Id,
                        ChildName = cLeft == null ? null : cLeft.Name
                    }
            );
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            optionsBuilder
                .UseSqlServer("server=(local);Database=EFDefiningQueryLeftJoin;Integrated Security=SSPI;")
                .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
        }
    }

Exception:

System.InvalidOperationException: 'Processing of the LINQ expression 'DbSet
.GroupJoin(
outer: DbSet,
inner: p => p.Id,
outerKeySelector: c => c.ParentId,
innerKeySelector: (p, outer) => new {
p = p,
outer = outer
})' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information.'

Further technical details

EF Core version: 3.1.1
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework:. NET Core 3.1
Operating system: Windows 10
IDE: Visual Studio 2019 16.4.4

@ChannelSix ChannelSix changed the title I can't a defining query that uses a left join I can't add a defining query that uses a left join Feb 8, 2020
@ajcvickers
Copy link
Member

@maumar to take a look.

@ajcvickers ajcvickers added this to the 5.0.0 milestone Feb 10, 2020
@maumar
Copy link
Contributor

maumar commented Feb 10, 2020

dupe of #19708

@maumar maumar closed this as completed Feb 10, 2020
@maumar
Copy link
Contributor

maumar commented Feb 10, 2020

@ChannelSix you can use QueryableExtensions.LeftJoin method directly as a workaround:

                modelBuilder.Entity<ParentChild>()
                    .HasNoKey()
                    .ToQuery(() =>
                        Set<Parent>().LeftJoin(Set<Child>(), k => k.Id, k => k.ParentId, (p, cLeft) => new ParentChild
                        {
                            ParentId = p.Id,
                            ParentName = p.Name,
                            ChildId = cLeft == null ? (int?)null : cLeft.Id,
                            ChildName = cLeft == null ? null : cLeft.Name
                        }));

QueryableExtensions is defined in Microsoft.EntityFrameworkCore.Internal namespace

@ChannelSix
Copy link
Author

Thanks for looking at this and the suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants