带OrderBy的EF查询失败

时间:2019-10-18 19:02:32

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

我确定对此有一个简单的答案,但是我似乎无法确定。

我有以下代码,

internal override async Task FetchDataModel()
{
    var dateCutoff = DateTime.Today.AddDays(-PeriodInDays);

     var query = this.DB.Jobs
         .IsDelivered()
         .Where(x => x.DeliveredTime.Value.Date >= dateCutoff)
         .GroupBy(x => new { x.Pet.OwnerId, x.Pet.Owner.First, x.Pet.Owner.Last })
         .Select(x => new MVPCustomerDTO
         {
             OwnerId = x.Key.OwnerId,
             OwnerName = $"{x.Key.First} {x.Key.Last}",
             JobCount = x.Count(),
             TotalSpend = x.Sum(a => (a.Price ?? 0M) - a.Discount) 
                      + this.DB.JobExtras
                               .Where(a => a.Job.Pet.OwnerId == x.Key.OwnerId)
                               .Where(a => a.Job.DeliveredTime.Value.Date >= dateCutoff)
                               .Sum(a => a.Price),
         })
/*==>Problem Line*/ .OrderByDescending(x => x.TotalSpend)
         .Take(25);

          var result = await query
                      .ToListAsync()
                      .ConfigureAwait(false);

          this.Model = result;
}

我不知道如何解决此异常。其EF核心3.0代码。 OrderByDescending导致了问题。如果删除它,查询将起作用。我以为可能与TotalSpend有关,因此尝试绕过这个问题,我删除了TotalSpend字段,将OrderByDescending更改为JobCount,获得了相同的结果。我敢肯定这与服务器端翻译有关,但是我似乎无法解决这个问题。

请帮我看看灯!?!

抛出的异常是:

 System.ArgumentNullException: Value cannot be null. (Parameter 'key')
    at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
    at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
    at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.GetMappedProjection(ProjectionMember projectionMember)
    at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitExtension(Expression extensionExpression)
    at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression)
    at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression)
    at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpression lambdaExpression)
    at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateOrderBy(ShapedQueryExpression source, LambdaExpression keySelector, Boolean ascending)
    at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
    at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
    at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
    at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
    at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
    at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
    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__DisplayClass12_0`1.<ExecuteAsync>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.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
    at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
    at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
    at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
    at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
    at GroomShop.Web.ReportGenerators.MVPCustomerReport.FetchDataModel() in C:\Workspace\GroomShop\GroomShop.Web\ReportGenerators\MVPCustomerReport.cs:line 203

3 个答案:

答案 0 :(得分:4)

该异常具有误导性。问题是投影(@oninput="@((e) => CalculationHere(e))" )内插的字符串,当然不能将其转换为SQL,并且应生成客户端评估异常来告诉您。而是(很可能是EF Core实现错误)您得到了上述令人误解的异常。

当然,解决方案是避免使用不可插补的构造/方法,例如插值字符串,带有格式字符串/区域性信息参数的Select / Format方法。相反,请使用字符串串联(如果需要,可以使用无参数的ToString方法),例如替换

ToString

使用

OwnerName = $"{x.Key.First} {x.Key.Last}",

答案 1 :(得分:0)

查询失败的原因可能是在某些数据库条目中Jobs.PetJobs.Pet.Owner为空。

当您随后在LINQ x.Key.OwnerId中访问x.Key.Firstx.Key.LastSelect()时,将引发异常

答案 2 :(得分:0)

当查询使用OrderByDescending()时,查询所查找的行比仅获取Top(25)的行还要多。 OrderBy必须点击所有有问题的行才能对其进行排序。一种可能是,您很幸运,Top(25)行没有命中任何空值。

如果是这种情况,则必须根据要求处理空值或将其从查询中排除。否则,将会发生其他情况。