【问题标题】:EF Core : Must be reducable nodeEF Core:必须是可简化节点
【发布时间】:2019-08-27 08:59:09
【问题描述】:

我收到“必须是可还原节点”错误。我相信这是一个错误,但是我无法解决它。

我是 DotNet Core 的最新稳定版本,并使用 Microsoft.EntityFrameworkCore 2.2.6。另外,我正在使用 Devart.DAta.Oracle.EFCore v9.7.805。

public async Task<DomainResult<IEnumerable<InternalRiskDto>>> GetRiskByPeriod(int customerNumber, bool resultForGuarantor, int numberofPeriod, CancellationToken ctx = default)
{
    Expression<Func<InternalRiscData, InternalRiskDto>> selectorExpression = r => new InternalRiskDto
    {
        A12 = r.IrdA12 ?? 0,
        A1224 = r.IrdA1224 ?? 0,
        A24 = r.IrdA24 ?? 0,
        AccNo = r.IrdAccNo,
        Branch = r.IrdBranch,
        Fincode = r.IrdFincode,
        Frees = r.IrdFrees,
        Ftahak = r.IrdFtahak,
        Idno = r.IrdIdno,
        Limit = r.IrdLimit < r.IrdA12 + r.IrdA1224 + r.IrdA24 ? r.IrdA12 + r.IrdA1224 + r.IrdA24 : r.IrdLimit,
        Crmno = resultForGuarantor ? r.IrdKcrmno : r.IrdMcrmno,
        Risccode = r.IrdRisccode,
        Riscdate = r.IrdRiscdate,
        Riscode2 = r.IrdRiscode2,
        Rowid = r.IrdRowid
    };

    Expression<Func<InternalRiscData, bool>> crmPredicate = x => ((resultForGuarantor && x.IrdKcrmno == customerNumber) || (!resultForGuarantor && x.IrdMcrmno == customerNumber));

    var dateQueryable = _riskRepository.GetQueryable()
        .Where(crmPredicate)
        .Select(x => x.IrdRiscdate)
        .Distinct()
        .OrderByDescending(x => x)
        .Take(numberofPeriod);

    var dateList = await dateQueryable.ToListAsync(ctx);

    if (!dateList.Any())
        return _errorDescriber.NoRiskRecordFound(customerNumber, numberofPeriod);

    var result = _riskRepository.GetQueryable()
        .Where(crmPredicate)
        .Where(ris => dateQueryable.Any(x => ris.IrdRiscdate == x)) //Problem arises here
        .Select(selectorExpression)
        .Distinct()
        .OrderByDescending(x => x.Riscdate).ThenBy(x => x.Risccode);

    return DomainResult<IEnumerable<InternalRiskDto>>.Success(await result.ToListAsync(ctx));
}

更新

NumberOfPeriods 是 5

堆栈跟踪:

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.ChildRewriter.Add(Expression expression) 
at System.Linq.Expressions.Compiler.StackSpiller.RewriteBinaryExpression(Expression expr, Stack stack) 
at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack) 
at System.Linq.Expressions.Compiler.StackSpiller.RewriteLogicalBinaryExpression(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.Compiler.StackSpiller.RewriteLambdaExpression(Expression expr) 
at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack) 
at System.Linq.Expressions.Compiler.StackSpiller.ChildRewriter.Add(Expression expression) 
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 expression) 
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 expression) 
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 expression) 
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 expression) 
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 expression) 
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 expression) 
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.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.CreateAsyncQueryExecutor[TResult](QueryModel queryModel) 
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler) 
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query) 
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.System.Collections.Generic.IAsyncEnumerable<TResult>.GetEnumerator() 
at System.Linq.AsyncEnumerable.Aggregate_[TSource,TAccumulate,TResult](IAsyncEnumerable`1 source, TAccumulate seed, Func`3 accumulator, Func`2 resultSelector, CancellationToken cancellationToken) in D:\\a\\1\\s\\Ix.NET\\Source\\System.Interactive.Async\\Aggregate.cs:line 128 
at WestCore.AppCore.Services.PRisk.LocalRiskPlusService.GetRiskByPeriod(Int32 customerNumber, Boolean resultForGuarantor, Int32 numberofPeriod, CancellationToken ctx) in C:\\Users\\<username>\\Source\\Workspaces\\CoreBankingWorkspace\\WestCoreApiSS\\Main\\WestCore.AppCore\\Services\\PRisk\\LocalRiskPlusService.cs:line 104 
at WestCore.Api.WestCore.V1.Controllers.PRisk.RiskFeedbackController.Get(Int32 customerNumber, Boolean resultForGuarantor, Nullable`1 startDate, Nullable`1 endDate, Nullable`1 numberOfPeriods) in C:\\Users\\<username>\\Source\\Workspaces\\CoreBankingWorkspace\\WestCoreApiSS\\Main\\WestCore.Api\\WestCore\\V1\\Controllers\\PRisk\\RiskFeedbackController.cs:line 43 
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) 
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync() 
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync() 
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context) 
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) 
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync() 
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() 
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context) 
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) 
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() 
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() 
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext) 
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext) 
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context) 
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext) 
at WestCore.Infrastructure.Middlewares.ErrorHandlingMiddleware.Invoke(HttpContext context, IHostingEnvironment env) in C:\\Users\\<username>\\Source\\Workspaces\\CoreBankingWorkspace\\WestCoreApiSS\\Main\\WestCore.Infrastructure\\Middlewares\\ErrorHandlingMiddleware.cs:line 32"

【问题讨论】:

  • :numberofPeriod 的值是多少
  • 问题已相应更新。
  • 不幸的是,异常堆栈跟踪只是确认这是 EF Core 错误/问题。您可以尝试用.Where(ris =&gt; dateList.Contains(ris.IrdRiscdate)) 替换.Where(ris =&gt; dateQueryable.Any(x =&gt; ris.IrdRiscdate == x)),看看是否能解决问题。如果没有,请提供相关类以便我们重现(我尝试过使用类似的查询形状,但无法重现,因此您的查询/模型中一定有特定的东西触发了该错误)。跨度>
  • 谢谢@IvanStoev。包含为我工作。似乎 Any 无法评估为 DB Query,因此 EF Core 尝试在本地评估它,但由于 EF Core 中的错误而出错。如果您可以将您的评论作为答案发布,这样我就可以标记它并为社区投票。
  • 不客气,很高兴它有帮助。请将其发布为自我回答(为了社区利益),我的评论只是猜测。

标签: c# linq .net-core entity-framework-core


【解决方案1】:

Contains 替换Any 对我有用。 Any 似乎无法评估为 DB Query,因此 EF Core 尝试在本地评估它,但由于 EF Core 中的错误而出错。

var result = _riskRepository.GetQueryable()
    ...
    .Where(ris => dateQueryable.Any(x => ris.IrdRiscdate == x)) //Problem arises here
    ...;

被替换为

var result = _riskRepository.GetQueryable()
    ...
    .Where(ris => dateList.Contains(ris.Riscdate))
    ...;

记录在案:此错误将在 EF Core 3.0 版中修复

特别感谢@IvanStoev

【讨论】:

    猜你喜欢
    • 2021-03-09
    • 2018-12-25
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    相关资源
    最近更新 更多