跳过/不使用EF核心中的左连接,给出“必须是可简化节点”错误

时间:2017-06-22 11:12:23

标签: entity-framework asp.net-core .net-core entity-framework-core pomelo

我的应用程序在.net核心指向1.1.1框架。 我使用的数据库提供程序是Pomelo.EntityFrameworkCore.MySql

我尝试执行的查询如下:

var queryEF = (from b in context.table1
                                orderby b.column1 descending
                                select new Table1
                                {
                                    column1 = b.column1,
                                });

queryEF = queryEF.Skip(3).Take(10).AsQueryable();

var query2 = (from b in queryEF
              join lb in context.table2
              on b.column1 equals lb.column1
              into tablejoin
              from blb in 
              tablejoin.DefaultIfEmpty()
              select new
              {
                 b.column1
              });

              if (query2 != null)
              {
                 foreach (var locnBranch in query2.AsEnumerable())
                 {
                 }
              }

执行AsEnumerable()时,上述查询失败。它抛出'必须是可简化的节点'错误。

异常详情:

{System.ArgumentException: must be reducible node
   at System.Linq.Expressions.Expression.ReduceAndCheck()
   at System.Linq.Expressions.Expression.ReduceExtensions()
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExtensionExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteMemberExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpressionFreeTemps(Expression expression, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.Rewrite[T](Expression`1 lambda)
   at System.Linq.Expressions.Expression`1.Accept(StackSpiller spiller)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteLambdaExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression node)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider expressions)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteMethodCallExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression node)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider expressions)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteMethodCallExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression node)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider expressions)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteMethodCallExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression node)
   at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider expressions)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteMethodCallExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpressionFreeTemps(Expression expression, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.Rewrite[T](Expression`1 lambda)
   at System.Linq.Expressions.Expression`1.Accept(StackSpiller spiller)
   at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda)
   at System.Linq.Expressions.Expression`1.Compile(Boolean preferInterpretation)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateExecutorLambda[TResults]()
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](Expression query, INodeTypeProvider nodeTypeProvider, IDatabase database, ILogger logger, Type contextType)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass19_0`1.<CompileQuery>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Remotion.Linq.QueryableBase`1.GetEnumerator()
   at GetAll() in E:\Test\Repository.cs:line 291
   at Get(List`1 Keys, String operatingCompany, Boolean isTrading, Int32 firstRecord, Int32 count, String clientIPAddress, String sortBy, String sortOrder) in E:\Test\Repository.cs:line 51
   at Get(List`1 Keys, String operatingCompany, Boolean isTrading, Int32 firstRecord, Int32 count, String clientIPAddress, String sortBy, String sortOrder) in E:\BusinessServices\Service.cs:line 121
   at Get(List`1 Keys, String operatingCompany, Boolean isTrading, Int32 firstRecord, Int32 count, String clientIPAddress, String sortBy, String sortOrder) in E:\Controllers\esController.cs:line 54
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionFilterAsync>d__28.MoveNext()}

上面的查询在删除skip / take之后工作正常。 我在EF5中测试了查询,它没有任何问题,只在EF核心中失败。

2 个答案:

答案 0 :(得分:0)

您是否尝试过将queryEF发送到List?另外,获取queryEf然后运行第二行代码跳过(3)的原因是什么.Take(10)?

var queryEF = (from b in context.table1
                            orderby b.column1 descending
                            select new Table1
                            {
                                column1 = b.column1,
                            }).Skip(3).Take(10).ToList();

而不是

queryEF = queryEF.Skip(3).Take(10).ToList();

如果这不起作用,那么不要让foreach循环尝试返回IEnumerable,而是使用.ToList()更改要在列表中指定的内容。

if (queryEF != null)
          {
             foreach (var locnBranch in queryEF.ToList())
             {
             }
          }

我相信你遇到的问题是foreach语句需要一个节点开始执行你正在提供的当前返回是一个通用的,它不包含一个Enumerable对象来迭代。通过将其作为List传递,您将提供迭代所需的那些节点。

祝你好运

我没有足够的声誉来评论抱歉

答案 1 :(得分:0)

我可以通过在queryEF查询结尾添加 .AsNoTracking()来解决这个问题。