System.Linq.Dynamic.Core icon indicating copy to clipboard operation
System.Linq.Dynamic.Core copied to clipboard

DefaultQueryAnalyzer.SupportsLinqToObjects is infinitely recursive.

Open ascott18 opened this issue 4 years ago • 0 comments

Here is what to include in your request to make sure we implement a solution as quickly as possible.

1. Description

When mixing EF Core, LinqKit's Expandable, and Linq Dynamic, Linq dynamic will infinitely recurse in DefaultQueryAnalyzer.SupportsLinqToObjects.

2. Exception

If you are seeing an exception, include the full exception details (message and stack trace).

   at System.Linq.Dynamic.Core.DefaultQueryableAnalyzer.SupportsLinqToObjects(System.Linq.IQueryable, System.Linq.IQueryProvider)
   at System.Linq.Dynamic.Core.DefaultQueryableAnalyzer.SupportsLinqToObjects(System.Linq.IQueryable, System.Linq.IQueryProvider)
   at System.Linq.Dynamic.Core.DefaultQueryableAnalyzer.SupportsLinqToObjects(System.Linq.IQueryable, System.Linq.IQueryProvider)
... the above is repeated ad infinitum until the program crashes.
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.SupportsLinqToObjects(System.Linq.Dynamic.Core.ParsingConfig, System.Linq.IQueryable)
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where(System.Linq.IQueryable, System.Linq.Dynamic.Core.ParsingConfig, System.String, System.Object[])
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Linq.IQueryable`1<System.__Canon>, System.Linq.Dynamic.Core.ParsingConfig, System.String, System.Object[])
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Linq.IQueryable`1<System.__Canon>, System.String, System.Object[])
   at Program.<Main>$(System.String[])

3. Fiddle or Project

using System.Linq;
using System.Linq.Expressions;
using System.Linq.Dynamic.Core;
using LinqKit;
using Microsoft.EntityFrameworkCore;

var db = new MyDb();

Expression<Func<MyChildEntity, int>> reusableExpression = x => x.Value;
var allowedValues = new List<int>{7};

var query = db.MyChildEntities
    .AsExpandable()
    .Where(x => allowedValues.Contains(reusableExpression.Invoke(x)))
    .Include(x => x.Parent)
    .Where("it.Id = 3");

query.ToList();

class MyDb : DbContext {
    public DbSet<MyEntity> MyEntities {get;set;}
    public DbSet<MyChildEntity> MyChildEntities {get;set;}

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseInMemoryDatabase("test");
    }
}

class MyEntity {
    public int Id {get;set;}
    public ICollection<MyChildEntity> Children {get;set;}
}

class MyChildEntity {
    public int Id {get;set;}
    public int ParentId {get;set;}
    public MyEntity Parent {get;set;}
    public int Value {get;set;}
}
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <RootNamespace>linq_dynamic_expandable</RootNamespace>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="LINQKit" Version="1.1.26" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.0-rc.2.21480.5" />
    <PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.13" />
  </ItemGroup>

</Project>

4. Any further technical details

The issue happens when the .Include is between the Expandable query and the Dynamic query. This is an except from my application's complex query pipeline - reordering these statements would require some significant refactoring, so that workaround isn't really feasible for me at the moment.

ascott18 avatar Nov 04 '21 19:11 ascott18