使用 linq 子查询查询 IQueryable 时失败

While querying IQueryable with linq subquery it fail

我只想使用从 EF Core 获取的 IQueryable 根据过滤器过滤客户,在本例中过滤器是另一个客户列表。

经过几个小时的搜索,我找到了 this,它看起来工作正常,然后我尝试这样做:

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

并得到这个神秘的错误:

System.InvalidOperationException
HResult=0x80131509
Message=Processing of the LINQ expression 'DbSet .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_01.<Execute>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func1 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.EntityQueryable1.GetEnumerator() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at MyProjectDir.shared.MyDbClass.Read(List1 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()

我找到的另一种选择是 ,我试过这个:

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

但在这种情况下,我得到这个错误:

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

假设您的 iqueryable 变量是一个 IQueryable<Customer>,并且您正尝试根据 customersListAsFilter 中的内容获取一部分客户,您可以执行以下操作:

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

生成的查询类似于:

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