Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

While querying IQueryable with linq subquery it fail

I just want use an IQueryable got from EFCore to filter customers against a filter, in this case the filter is another list of customers.

After hours of search I found this and it looks works ok, then I tried do this:

List<Customer> filteredCustomers = iqueryable.Join(customersListAsFilter.Select(F => F.Id), F => F.Id, Id => Id, (T, S) => T).ToList<Customer>();  

and got this cryptic error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

System.InvalidOperationException
  HResult=0x80131509
  Message=Processing of the LINQ expression 'DbSet<Customer>
    .Join(
        outer: __p_0, 
        inner: F => F.Id, 
        outerKeySelector: Id => Id, 
        innerKeySelector: (T, S) => T)' 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.
  Source=Microsoft.EntityFrameworkCore
  StackTrace:
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.Expand(Expression query)
   at Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessor.Process(Expression query)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at MyProjectDir.shared.MyDbClass.Read(List`1 customers) in C:\MyProjectDir\shared\MyDbClass.cs:line 35
   at MyProjectDir.shared.MyDbClass.Read(Customer customer) in C:\MyProjectDir\shared\MyDbClass.cs:line 42
   at WTAPP.Controllers.CustomerController.Get(Int32 Id) in C:\MyProjectDir\MyWebProj\CustomerController.cs:line 37
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()

Another alternative i found was this and I tried this:

var result = q.GroupBy(target => target.Id)
                   .Where(target => target.Select(T => T.Id)
                               .OrderBy(Id => Id)
                               .SequenceEqual(customersListAsFilter));

to receive as error this:

Error   CS1929  'IOrderedEnumerable<int>' does not contain a definition for 'SequenceEqual' and the best extension method overload 'ParallelEnumerable.SequenceEqual<Customer>(ParallelQuery<Customer>, IEnumerable<Customer>)' requires a receiver of type 'ParallelQuery<Customer>'   

>Solution :

Assuming your iqueryable variable is an IQueryable<Customer>, and you are trying to get a subset of customers based on what you have in customersListAsFilter, you can do the following:

List<int> customersToGet = customersListAsFilter.Select(x => x.Id).ToList();
List<Customer> filteredCustomers = iqueryable.Where(x => customersToGet.Contains(x.Id)).ToList();

The generated query will be something like:

select * -- (column names)
from Customers
where Id in (1,2,3,4,5,6) -- the IDs from customersToGet
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading