C# 带有OrderBy的EF查询失败

C# 带有OrderBy的EF查询失败,c#,entity-framework,linq,entity-framework-core,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 >= da

我相信有一个简单的答案,但我似乎无法确定

我有以下代码

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导致了问题。如果我删除它,查询就会工作。我认为这可能与TotalExpense有关,所以我试图绕开它,删除了TotalExpense字段,将OrderByDescending更改为OrderByJobCount,得到了相同的结果。我确信这与服务器端翻译有关,但我似乎无法用头脑来解决这个问题

请帮我看看灯

抛出的异常是:

 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
System.ArgumentNullException:值不能为null。(参数“key”)
at System.Collections.Generic.Dictionary`2.FindEntry(TKey)
在System.Collections.Generic.Dictionary`2.get_项(TKey)
在Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.GetMappedProjection(ProjectionMember ProjectionMember)
位于Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisiTexttension(表达式扩展Expression)
位于Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(表达式)
在Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslationExpressionVisitor.TranslateExpression(表达式)中
在Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslationExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression ShapedQueryExpression,LambdaExpression LambdaExpression)
位于Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslationExpressionVisitor.TranslateOrderBy(ShapedQueryExpression源、LambdaExpression键选择器、布尔升序)
在Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslationExpressionVisitor.VisitMethodCall调用(MethodCallExpression MethodCallExpression)
位于Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslationExpressionVisitor.VisitMethodCallExpression(MethodCallExpression MethodCallExpression)
位于System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor)
在Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslationExpressionVisitor.VisitMethodCall调用(MethodCallExpression MethodCallExpression)
位于Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslationExpressionVisitor.VisitMethodCallExpression(MethodCallExpression MethodCallExpression)
位于System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor)
位于Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](表达式查询)
位于Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](表达式查询,布尔异步)
位于Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase数据库、表达式查询、IModel模型、布尔异步)
在Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.c__显示Class12_0`1.b__0()
位于Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](对象缓存键,Func`1编译器)
位于Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOradQuery[TResult](对象缓存键,Func`1编译器)
在Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](表达式查询,取消令牌取消令牌)
在Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](表达式表达式,CancellationToken CancellationToken)
位于Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken CancellationToken)
在System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()中
位于Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListSync[TSource](IQueryable`1源,CancellationToken CancellationToken)
在C:\Workspace\GroomShop\GroomShop.Web\ReportGenerators\MVPCustomerReport.FetchDataModel()中的GroomShop.Web.ReportGenerators.MVPCustomerReport.cs:第203行

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


然后在LINQ
Select()
中访问
x.Key.OwnerId
x.Key.First
x.Key.Last
时,它将抛出异常

该异常具有误导性。问题是投影(
Select
)中的插值字符串,它当然不能转换为SQL,应该会生成客户端计算异常,告诉您这一点。相反(最有可能是EF核心实现错误),您会得到上述误导性异常

当然,解决方案是避免不可翻译的构造/方法,如插入字符串、
Format
/
ToString
方法和格式字符串/区域性信息参数。相反,使用字符串连接(以及无参数的
ToString
方法,如果需要),例如替换

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


当查询使用OrderByDescending()时,查询查看的行比只查看顶部(25)的行更多。OrderBy必须点击所有有问题的行才能进行排序。一种可能性是,您很幸运,最上面(25)行没有碰到任何空值


如果是这种情况,则必须处理空值,或者从查询中排除空值,具体取决于需求。否则,就会有别的事情发生。

只是好奇而已。。。您的查询是否有可用的SQL版本?如果是,你能分享吗?我经常发现,在LINQ中创建复杂查询时,如果我有一个可以运行的SQL查询来构建,它会变得更容易。请为Pet.Owner添加Include。我猜,x.Key.First可能是空的。伊万有答案。。这是字符串插值。奇怪的是,如果
OwnerName = x.Key.First + " " + x.Key.Last,