EF Core 2.1.2和.net core 2.0-Linq2Entities导致“必须还原的节点”错误

时间:2018-07-17 10:55:56

标签: entity-framework linq entity-framework-core asp.net-core-2.0

我调查了几个小时以找到解决问题的方法或解决方法。我发现的唯一错误是与Linq Join或更旧的EF版本一起出现的“必须是可还原节点”。所以我不得不再次问这个问题。

当前环境:

  • VS2017
  • .net core 2.0项目
  • EntityFramework Core 2.1.2

此错误的我的源代码为:

    // this query works...
var projectEfforts = from projectEntry in _context.ProjectTrackingEntry
                     where projectEntry.ProjectId == projectId
                     group projectEntry by new { projectEntry.Day.Year, projectEntry.Day.Month } into g
                     select new
                     {
                         PeDate = new DateTime(g.Key.Year, g.Key.Month, 1),
                         Month = g.Key,
                         MonthlyWorkingHours = g.Sum(x => x.WorkingHours)
                     };

// and here the query is executed with a valid result
string jsonprojectEfforts = Newtonsoft.Json.JsonConvert.SerializeObject(projectEfforts);

// following Linq will produce an error
var effHours = from projectEffort in projectEfforts
               where (projectEffort.PeDate < fromDate)
               select projectEffort.MonthlyWorkingHours;

// work with the result above will cause the 'must be reducible node' error
string jsoneffHours = Newtonsoft.Json.JsonConvert.SerializeObject(effHours);

为了更好地理解,这是第一次Linq操作的结果:

  

[{“ PeDate”:“ 2017-01-01T00:00:00”,“ Month”:{“ Year”:2017,“ Month”:1},“ MonthlyWorkingHours”:128.00}   ,{“ PeDate”:“ 2018-01-01T00:00:00”,“ Month”:{“ Year”:2018,“ Month”:1},“ MonthlyWorkingHours”:40.00}   ,{“ PeDate”:“ 2017-02-01T00:00:00”,“ Month”:{“ Year”:2017,“ Month”:2},“ MonthlyWorkingHours”:80.00}   ,{“ PeDate”:“ 2017-03-01T00:00:00”,“ Month”:{“ Year”:2017,“ Month”:3},“ MonthlyWorkingHours”:88.00}   ,{“ PeDate”:“ 2018-03-01T00:00:00”,“ Month”:{“ Year”:2018,“ Month”:3},“ MonthlyWorkingHours”:64.00}   ,{“ PeDate”:“ 2017-04-01T00:00:00”,“ Month”:{“ Year”:2017,“ Month”:4},“ MonthlyWorkingHours”:104.00}   ,{“ PeDate”:“ 2018-04-01T00:00:00”,“ Month”:{“ Year”:2018,“ Month”:4},“ MonthlyWorkingHours”:76.00}   ,{“ PeDate”:“ 2017-05-01T00:00:00”,“ Month”:{“ Year”:2017,“ Month”:5},“ MonthlyWorkingHours”:16.00}   ,{“ PeDate”:“ 2018-05-01T00:00:00”,“ Month”:{“ Year”:2018,“ Month”:5},“ MonthlyWorkingHours”:24.00}   ,{“ PeDate”:“ 2017-06-01T00:00:00”,“ Month”:{“ Year”:2017,“ Month”:6},“ MonthlyWorkingHours”:60.00}   ,{“ PeDate”:“ 2018-06-01T00:00:00”,“ Month”:{“ Year”:2018,“ Month”:6},“ MonthlyWorkingHours”:24.00}   ,{“ PeDate”:“ 2017-07-01T00:00:00”,“ Month”:{“ Year”:2017,“ Month”:7},“ MonthlyWorkingHours”:48.00}   ,{“ PeDate”:“ 2018-07-01T00:00:00”,“ Month”:{“ Year”:2018,“ Month”:7},“ MonthlyWorkingHours”:80.00}   ,{“ PeDate”:“ 2017-08-01T00:00:00”,“ Month”:{“ Year”:2017,“ Month”:8},“ MonthlyWorkingHours”:104.00}   ,{“ PeDate”:“ 2017-09-01T00:00:00”,“ Month”:{“ Year”:2017,“ Month”:9},“ MonthlyWorkingHours”:48.00}   ,{“ PeDate”:“ 2017-10-01T00:00:00”,“ Month”:{“ Year”:2017,“ Month”:10},“ MonthlyWorkingHours”:72.00}   ,{“ PeDate”:“ 2017-12-01T00:00:00”,“ Month”:{“ Year”:2017,“ Month”:12},“ MonthlyWorkingHours”:213.75}]

然后第二次Linq操作(effHours)发生错误 ,原因是尝试将结果序列化为JSON(上面代码段中的最后代码行):

  

在System.Linq.Expressions.Expression.ReduceAndCheck()      在System.Linq.Expressions.Expression.ReduceExtensions()      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExtensionExpression(Expression expr,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression节点,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteMemberExpression(Expression expr,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression节点,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteMemberExpression(Expression expr,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression节点,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression表达式)      在System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider表达式)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteNewExpression(Expression expr,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression节点,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression表达式)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteBinaryExpression(Expression expr,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression节点,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExpressionFreeTemps(Expression expression,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.Rewrite [T](Expression 1 lambda) at System.Linq.Expressions.Expression 1.Accept(StackSpiller溢出器)中      在System.Linq.Expressions.Compiler.StackSpiller.RewriteLambdaExpression(Expression expr)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression节点,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression表达式)      在System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider表达式)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteMethodCallExpression(Expression expr,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression节点,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression表达式)      在System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider表达式)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteMethodCallExpression(Expression expr,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression节点,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression表达式)      在System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.AddArguments(IArgumentProvider表达式)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteMethodCallExpression(Expression expr,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression节点,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.RewriteExpressionFreeTemps(Expression expression,堆栈堆栈)      在System.Linq.Expressions.Compiler.StackSpiller.Rewrite [T](Expression 1 lambda) at System.Linq.Expressions.Expression 1.Accept(StackSpiller溢出器)中      在System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda)      在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, IQueryModelGenerator queryModelGenerator, IDatabase database, IDiagnosticsLogger 1记录器处,键入contextType)      在Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler。<> c__DisplayClass13_0 1.<Execute>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func 1编译器处)      在Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute [TResult](表达式查询)      在Remotion.Linq.QueryableBase`1.System.Collections.IEnumerable.GetEnumerator()      在Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter作家,IEnumerable值,JsonArrayContract合同,JsonProperty成员,JsonContainerContract collectionContract,JsonProperty containerProperty)      在Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter,对象值,类型objectType)      在Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter,Object value,Type objectType)      在Newtonsoft.Json.JsonConvert.SerializeObjectInternal(对象值,类型,JsonSerializer jsonSerializer)      在C:\ Sources中的My.api.MyController.MyServiceMethod(Guid projectId,DateTime fromDate,DateTime toDate)[...] MyController.cs:line 347


因为这一切都在幕后,所以我不知道如何解决该问题。我也对解决方法或某些提示感到满意。

有人可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

您的projectEfforts不是 集合。这是一个查询,您正在运行两次。第二次产生错误。

因此,您的解决方法是只运行一次查询,然后从结果中获取effHours而不是进行第二次查询。

var projectEffortsQuery = from projectEntry in _context.ProjectTrackingEntry
                     where projectEntry.ProjectId == projectId
                     group projectEntry by new { projectEntry.Day.Year, projectEntry.Day.Month } into g
                     select new
                     {
                         PeDate = new DateTime(g.Key.Year, g.Key.Month, 1),
                         Month = g.Key,
                         MonthlyWorkingHours = g.Sum(x => x.WorkingHours)
                     };

var projectEfforts = projectEffortsQuery.ToList();